﻿// Accord Math Library
// The Accord.NET Framework
// http://accord-framework.net
//
// Copyright © César Souza, 2009-2017
// cesarsouza at gmail.com
//
//    This library is free software; you can redistribute it and/or
//    modify it under the terms of the GNU Lesser General Public
//    License as published by the Free Software Foundation; either
//    version 2.1 of the License, or (at your option) any later version.
//
//    This library is distributed in the hope that it will be useful,
//    but WITHOUT ANY WARRANTY; without even the implied warranty of
//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
//    Lesser General Public License for more details.
//
//    You should have received a copy of the GNU Lesser General Public
//    License along with this library; if not, write to the Free Software
//    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
//

// ======================================================================
// This code has been generated by a tool; do not edit manually. Instead,
// edit the T4 template Vector.Range.tt so this file can be regenerated. 
// ======================================================================


namespace Accord.Math
{
    using System;
    using System.Collections.Generic;
    using Accord.Math;

    public static partial class Vector
    {

        /// <summary>
        ///   Creates a range vector (like NumPy's arange function).
        /// </summary>
        /// 
        /// <param name="n">The exclusive upper bound of the range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static int[] Range(int n)
        {
            int[] r = new int[(int)n]; 
            for (int i = 0; i < r.Length; i++)
                r[i] = (int)i;
            return r;
        }

        /// <summary>
        ///   Creates a range vector (like NumPy's arange function).
        /// </summary>
        ///
        /// <param name="a">The inclusive lower bound of the range.</param>
        /// <param name="b">The exclusive upper bound of the range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static int[] Range(int a, int b)
        {
            if (a == b)
                return new int[] { };

            int[] r;

            if (b > a)
            {
                r = new int[(int)(b - a)];
                for (int i = 0; i < r.Length; i++)
                    r[i] = (int)(a++);
            }
            else
            {
                r = new int[(int)(a - b)];
                for (int i = 0; i < r.Length; i++)
                    r[i] = (int)(a--);
            }

            return r;
        }

        /// <summary>
        ///   Enumerates through a range (like Python's xrange function).
        /// </summary>
        /// 
        /// <param name="n">The exclusive upper bound of the range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static IEnumerable<int> EnumerableRange(int n)
        {
            for (int i = 0; i < n; i++)
                yield return (int)i;
        }

        /// <summary>
        ///   Enumerates through a range (like Python's xrange).
        /// </summary>
        /// 
        /// <param name="a">The inclusive lower bound of the range.</param>
        /// <param name="b">The exclusive upper bound of the range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static IEnumerable<int> EnumerableRange(int a, int b)
        {
            if (a == b)
                yield break;

            if (b > a)
            {
                int n = (int)(b - a);
                for (int i = 0; i < n; i++)
                    yield return (int)(a++);
            }
            else
            {
                int n = (int)(a - b);
                for (int i = 0; i < n; i++)
                    yield return (int)(a--);
            }
        }


        /// <summary>
        ///   Creates a range vector (like NumPy's arange function).
        /// </summary>
        /// 
        /// <param name="a">The inclusive lower bound of the range.</param>
        /// <param name="b">The exclusive upper bound of the range.</param>
        /// <param name="stepSize">The step size to be taken between elements. 
        ///   This parameter can be negative to create a decreasing range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static int[] Range(int a, int b, int stepSize)
        {
            if (a == b)
                return new int[] { };

            if (stepSize == 0)
                throw new ArgumentOutOfRangeException("stepSize", "stepSize must be different from zero.");

            int[] r;

            if (a < b)
            {
                if (stepSize < 0)
                    throw new ArgumentOutOfRangeException("stepSize", "If a < b, stepSize must be positive.");

                uint steps = (uint)System.Math.Ceiling(((double)(b - a) / (double)stepSize));

                r = new int[steps];
                for (uint i = 0; i < r.Length; i++)
                    r[i] = (int)(a +  i * stepSize);
            }
            else
            {
                if (stepSize > 0)
                {
                    uint steps = (uint)System.Math.Ceiling(((double)(a - b) / (double)stepSize));
                    r = new int[steps];
                    for (uint i = 0; i < r.Length; i++)
                        r[i] = (int)(a - i * stepSize);
                }
                else
                {
                    uint steps = (uint)System.Math.Ceiling(((double)(b - a) / (double)stepSize));
                    r = new int[steps];
                    for (uint i = 0; i < r.Length; i++)
                        r[i] = (int)(a + i * stepSize);
                }
            }

            if (a < b)
            {
                if (r[r.Length - 1] > b)
                    r[r.Length - 1] = b;
            }
            else
            {
                if (r[r.Length - 1] > a)
                    r[r.Length - 1] = a;
            }

            return r;
        }

        /// <summary>
        ///   Enumerates through a range (like Python's xrange function).
        /// </summary>
        /// 
        /// <param name="a">The inclusive lower bound of the range.</param>
        /// <param name="b">The exclusive upper bound of the range.</param>
        /// <param name="stepSize">The step size to be taken between elements. 
        ///   This parameter can be negative to create a decreasing range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static IEnumerable<int> EnumerableRange(int a, int b, int stepSize)
        {
            if (a == b)
                yield break;

            if (stepSize == 0)
                throw new ArgumentOutOfRangeException("stepSize", "stepSize must be different from zero.");

            int last;

            if (a < b)
            {
                if (stepSize < 0)
                    throw new ArgumentOutOfRangeException("stepSize", "If a < b, stepSize must be positive.");

                uint steps = (uint)System.Math.Ceiling(((double)(b - a) / (double)stepSize)) - 1;
                for (uint i = 0; i < steps; i++)
                    yield return (int)(a +  i * stepSize);
                last = (int)(a +  steps * stepSize);
            }
            else
            {
                if (stepSize > 0)
                {
                    uint steps = (uint)System.Math.Ceiling(((double)(a - b) / (double)stepSize)) - 1;
                    for (uint i = 0; i < steps; i++)
                        yield return (int)(a - i * stepSize);
                    last = (int)(a - steps * stepSize);
                }
                else
                {
                    uint steps = (uint)System.Math.Ceiling(((double)(b - a) / (double)stepSize)) - 1;
                    for (uint i = 0; i < steps; i++)
                        yield return (int)(a + i * stepSize);
                    last = (int)(a + steps * stepSize);
                }
            }

            if (a < b)
            {
                yield return last > b ? b : last;
            }
            else
            {
                yield return last > a ? a : last;
            }
        }

        /// <summary>
        ///   Creates a range vector (like NumPy's arange function).
        /// </summary>
        /// 
        /// <param name="a">The inclusive lower bound of the range.</param>
        /// <param name="b">The exclusive upper bound of the range.</param>
        /// <param name="stepSize">The step size to be taken between elements. 
        ///   This parameter can be negative to create a decreasing range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static float[] Range(int a, int b, float stepSize)
        {
            if (a == b)
                return new float[] { };

            if (stepSize == 0)
                throw new ArgumentOutOfRangeException("stepSize", "stepSize must be different from zero.");

            float[] r;

            if (a < b)
            {
                if (stepSize < 0)
                    throw new ArgumentOutOfRangeException("stepSize", "If a < b, stepSize must be positive.");

                uint steps = (uint)System.Math.Ceiling(((float)(b - a) / (float)stepSize));

                r = new float[steps];
                for (uint i = 0; i < r.Length; i++)
                    r[i] = (float)(a +  i * stepSize);
            }
            else
            {
                if (stepSize > 0)
                {
                    uint steps = (uint)System.Math.Ceiling(((float)(a - b) / (float)stepSize));
                    r = new float[steps];
                    for (uint i = 0; i < r.Length; i++)
                        r[i] = (float)(a - i * stepSize);
                }
                else
                {
                    uint steps = (uint)System.Math.Ceiling(((float)(b - a) / (float)stepSize));
                    r = new float[steps];
                    for (uint i = 0; i < r.Length; i++)
                        r[i] = (float)(a + i * stepSize);
                }
            }

            if (a < b)
            {
                if (r[r.Length - 1] > b)
                    r[r.Length - 1] = b;
            }
            else
            {
                if (r[r.Length - 1] > a)
                    r[r.Length - 1] = a;
            }

            return r;
        }

        /// <summary>
        ///   Enumerates through a range (like Python's xrange function).
        /// </summary>
        /// 
        /// <param name="a">The inclusive lower bound of the range.</param>
        /// <param name="b">The exclusive upper bound of the range.</param>
        /// <param name="stepSize">The step size to be taken between elements. 
        ///   This parameter can be negative to create a decreasing range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static IEnumerable<float> EnumerableRange(int a, int b, float stepSize)
        {
            if (a == b)
                yield break;

            if (stepSize == 0)
                throw new ArgumentOutOfRangeException("stepSize", "stepSize must be different from zero.");

            float last;

            if (a < b)
            {
                if (stepSize < 0)
                    throw new ArgumentOutOfRangeException("stepSize", "If a < b, stepSize must be positive.");

                uint steps = (uint)System.Math.Ceiling(((float)(b - a) / (float)stepSize)) - 1;
                for (uint i = 0; i < steps; i++)
                    yield return (float)(a +  i * stepSize);
                last = (float)(a +  steps * stepSize);
            }
            else
            {
                if (stepSize > 0)
                {
                    uint steps = (uint)System.Math.Ceiling(((float)(a - b) / (float)stepSize)) - 1;
                    for (uint i = 0; i < steps; i++)
                        yield return (float)(a - i * stepSize);
                    last = (float)(a - steps * stepSize);
                }
                else
                {
                    uint steps = (uint)System.Math.Ceiling(((float)(b - a) / (float)stepSize)) - 1;
                    for (uint i = 0; i < steps; i++)
                        yield return (float)(a + i * stepSize);
                    last = (float)(a + steps * stepSize);
                }
            }

            if (a < b)
            {
                yield return last > b ? b : last;
            }
            else
            {
                yield return last > a ? a : last;
            }
        }

        /// <summary>
        ///   Creates a range vector (like NumPy's arange function).
        /// </summary>
        /// 
        /// <param name="a">The inclusive lower bound of the range.</param>
        /// <param name="b">The exclusive upper bound of the range.</param>
        /// <param name="stepSize">The step size to be taken between elements. 
        ///   This parameter can be negative to create a decreasing range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static double[] Range(int a, int b, double stepSize)
        {
            if (a == b)
                return new double[] { };

            if (stepSize == 0)
                throw new ArgumentOutOfRangeException("stepSize", "stepSize must be different from zero.");

            double[] r;

            if (a < b)
            {
                if (stepSize < 0)
                    throw new ArgumentOutOfRangeException("stepSize", "If a < b, stepSize must be positive.");

                uint steps = (uint)System.Math.Ceiling(((double)(b - a) / (double)stepSize));

                r = new double[steps];
                for (uint i = 0; i < r.Length; i++)
                    r[i] = (double)(a +  i * stepSize);
            }
            else
            {
                if (stepSize > 0)
                {
                    uint steps = (uint)System.Math.Ceiling(((double)(a - b) / (double)stepSize));
                    r = new double[steps];
                    for (uint i = 0; i < r.Length; i++)
                        r[i] = (double)(a - i * stepSize);
                }
                else
                {
                    uint steps = (uint)System.Math.Ceiling(((double)(b - a) / (double)stepSize));
                    r = new double[steps];
                    for (uint i = 0; i < r.Length; i++)
                        r[i] = (double)(a + i * stepSize);
                }
            }

            if (a < b)
            {
                if (r[r.Length - 1] > b)
                    r[r.Length - 1] = b;
            }
            else
            {
                if (r[r.Length - 1] > a)
                    r[r.Length - 1] = a;
            }

            return r;
        }

        /// <summary>
        ///   Enumerates through a range (like Python's xrange function).
        /// </summary>
        /// 
        /// <param name="a">The inclusive lower bound of the range.</param>
        /// <param name="b">The exclusive upper bound of the range.</param>
        /// <param name="stepSize">The step size to be taken between elements. 
        ///   This parameter can be negative to create a decreasing range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static IEnumerable<double> EnumerableRange(int a, int b, double stepSize)
        {
            if (a == b)
                yield break;

            if (stepSize == 0)
                throw new ArgumentOutOfRangeException("stepSize", "stepSize must be different from zero.");

            double last;

            if (a < b)
            {
                if (stepSize < 0)
                    throw new ArgumentOutOfRangeException("stepSize", "If a < b, stepSize must be positive.");

                uint steps = (uint)System.Math.Ceiling(((double)(b - a) / (double)stepSize)) - 1;
                for (uint i = 0; i < steps; i++)
                    yield return (double)(a +  i * stepSize);
                last = (double)(a +  steps * stepSize);
            }
            else
            {
                if (stepSize > 0)
                {
                    uint steps = (uint)System.Math.Ceiling(((double)(a - b) / (double)stepSize)) - 1;
                    for (uint i = 0; i < steps; i++)
                        yield return (double)(a - i * stepSize);
                    last = (double)(a - steps * stepSize);
                }
                else
                {
                    uint steps = (uint)System.Math.Ceiling(((double)(b - a) / (double)stepSize)) - 1;
                    for (uint i = 0; i < steps; i++)
                        yield return (double)(a + i * stepSize);
                    last = (double)(a + steps * stepSize);
                }
            }

            if (a < b)
            {
                yield return last > b ? b : last;
            }
            else
            {
                yield return last > a ? a : last;
            }
        }

        /// <summary>
        ///   Creates a range vector (like NumPy's arange function).
        /// </summary>
        /// 
        /// <param name="n">The exclusive upper bound of the range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static float[] Range(float n)
        {
            float[] r = new float[(int)n]; 
            for (int i = 0; i < r.Length; i++)
                r[i] = (float)i;
            return r;
        }

        /// <summary>
        ///   Creates a range vector (like NumPy's arange function).
        /// </summary>
        ///
        /// <param name="a">The inclusive lower bound of the range.</param>
        /// <param name="b">The exclusive upper bound of the range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static float[] Range(float a, float b)
        {
            if (a == b)
                return new float[] { };

            float[] r;

            if (b > a)
            {
                r = new float[(int)(b - a)];
                for (int i = 0; i < r.Length; i++)
                    r[i] = (float)(a++);
            }
            else
            {
                r = new float[(int)(a - b)];
                for (int i = 0; i < r.Length; i++)
                    r[i] = (float)(a--);
            }

            return r;
        }

        /// <summary>
        ///   Enumerates through a range (like Python's xrange function).
        /// </summary>
        /// 
        /// <param name="n">The exclusive upper bound of the range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static IEnumerable<float> EnumerableRange(float n)
        {
            for (float i = 0; i < n; i++)
                yield return (float)i;
        }

        /// <summary>
        ///   Enumerates through a range (like Python's xrange).
        /// </summary>
        /// 
        /// <param name="a">The inclusive lower bound of the range.</param>
        /// <param name="b">The exclusive upper bound of the range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static IEnumerable<float> EnumerableRange(float a, float b)
        {
            if (a == b)
                yield break;

            if (b > a)
            {
                int n = (int)(b - a);
                for (int i = 0; i < n; i++)
                    yield return (float)(a++);
            }
            else
            {
                int n = (int)(a - b);
                for (int i = 0; i < n; i++)
                    yield return (float)(a--);
            }
        }


        /// <summary>
        ///   Creates a range vector (like NumPy's arange function).
        /// </summary>
        /// 
        /// <param name="a">The inclusive lower bound of the range.</param>
        /// <param name="b">The exclusive upper bound of the range.</param>
        /// <param name="stepSize">The step size to be taken between elements. 
        ///   This parameter can be negative to create a decreasing range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static float[] Range(float a, float b, int stepSize)
        {
            if (a == b)
                return new float[] { };

            if (stepSize == 0)
                throw new ArgumentOutOfRangeException("stepSize", "stepSize must be different from zero.");

            float[] r;

            if (a < b)
            {
                if (stepSize < 0)
                    throw new ArgumentOutOfRangeException("stepSize", "If a < b, stepSize must be positive.");

                uint steps = (uint)System.Math.Ceiling(((float)(b - a) / (float)stepSize));

                r = new float[steps];
                for (uint i = 0; i < r.Length; i++)
                    r[i] = (float)(a +  i * stepSize);
            }
            else
            {
                if (stepSize > 0)
                {
                    uint steps = (uint)System.Math.Ceiling(((float)(a - b) / (float)stepSize));
                    r = new float[steps];
                    for (uint i = 0; i < r.Length; i++)
                        r[i] = (float)(a - i * stepSize);
                }
                else
                {
                    uint steps = (uint)System.Math.Ceiling(((float)(b - a) / (float)stepSize));
                    r = new float[steps];
                    for (uint i = 0; i < r.Length; i++)
                        r[i] = (float)(a + i * stepSize);
                }
            }

            if (a < b)
            {
                if (r[r.Length - 1] > b)
                    r[r.Length - 1] = b;
            }
            else
            {
                if (r[r.Length - 1] > a)
                    r[r.Length - 1] = a;
            }

            return r;
        }

        /// <summary>
        ///   Enumerates through a range (like Python's xrange function).
        /// </summary>
        /// 
        /// <param name="a">The inclusive lower bound of the range.</param>
        /// <param name="b">The exclusive upper bound of the range.</param>
        /// <param name="stepSize">The step size to be taken between elements. 
        ///   This parameter can be negative to create a decreasing range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static IEnumerable<float> EnumerableRange(float a, float b, int stepSize)
        {
            if (a == b)
                yield break;

            if (stepSize == 0)
                throw new ArgumentOutOfRangeException("stepSize", "stepSize must be different from zero.");

            float last;

            if (a < b)
            {
                if (stepSize < 0)
                    throw new ArgumentOutOfRangeException("stepSize", "If a < b, stepSize must be positive.");

                uint steps = (uint)System.Math.Ceiling(((float)(b - a) / (float)stepSize)) - 1;
                for (uint i = 0; i < steps; i++)
                    yield return (float)(a +  i * stepSize);
                last = (float)(a +  steps * stepSize);
            }
            else
            {
                if (stepSize > 0)
                {
                    uint steps = (uint)System.Math.Ceiling(((float)(a - b) / (float)stepSize)) - 1;
                    for (uint i = 0; i < steps; i++)
                        yield return (float)(a - i * stepSize);
                    last = (float)(a - steps * stepSize);
                }
                else
                {
                    uint steps = (uint)System.Math.Ceiling(((float)(b - a) / (float)stepSize)) - 1;
                    for (uint i = 0; i < steps; i++)
                        yield return (float)(a + i * stepSize);
                    last = (float)(a + steps * stepSize);
                }
            }

            if (a < b)
            {
                yield return last > b ? b : last;
            }
            else
            {
                yield return last > a ? a : last;
            }
        }

        /// <summary>
        ///   Creates a range vector (like NumPy's arange function).
        /// </summary>
        /// 
        /// <param name="a">The inclusive lower bound of the range.</param>
        /// <param name="b">The exclusive upper bound of the range.</param>
        /// <param name="stepSize">The step size to be taken between elements. 
        ///   This parameter can be negative to create a decreasing range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static float[] Range(float a, float b, float stepSize)
        {
            if (a == b)
                return new float[] { };

            if (stepSize == 0)
                throw new ArgumentOutOfRangeException("stepSize", "stepSize must be different from zero.");

            float[] r;

            if (a < b)
            {
                if (stepSize < 0)
                    throw new ArgumentOutOfRangeException("stepSize", "If a < b, stepSize must be positive.");

                uint steps = (uint)System.Math.Ceiling(((double)(b - a) / (double)stepSize));

                r = new float[steps];
                for (uint i = 0; i < r.Length; i++)
                    r[i] = (float)(a +  i * stepSize);
            }
            else
            {
                if (stepSize > 0)
                {
                    uint steps = (uint)System.Math.Ceiling(((double)(a - b) / (double)stepSize));
                    r = new float[steps];
                    for (uint i = 0; i < r.Length; i++)
                        r[i] = (float)(a - i * stepSize);
                }
                else
                {
                    uint steps = (uint)System.Math.Ceiling(((double)(b - a) / (double)stepSize));
                    r = new float[steps];
                    for (uint i = 0; i < r.Length; i++)
                        r[i] = (float)(a + i * stepSize);
                }
            }

            if (a < b)
            {
                if (r[r.Length - 1] > b)
                    r[r.Length - 1] = b;
            }
            else
            {
                if (r[r.Length - 1] > a)
                    r[r.Length - 1] = a;
            }

            return r;
        }

        /// <summary>
        ///   Enumerates through a range (like Python's xrange function).
        /// </summary>
        /// 
        /// <param name="a">The inclusive lower bound of the range.</param>
        /// <param name="b">The exclusive upper bound of the range.</param>
        /// <param name="stepSize">The step size to be taken between elements. 
        ///   This parameter can be negative to create a decreasing range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static IEnumerable<float> EnumerableRange(float a, float b, float stepSize)
        {
            if (a == b)
                yield break;

            if (stepSize == 0)
                throw new ArgumentOutOfRangeException("stepSize", "stepSize must be different from zero.");

            float last;

            if (a < b)
            {
                if (stepSize < 0)
                    throw new ArgumentOutOfRangeException("stepSize", "If a < b, stepSize must be positive.");

                uint steps = (uint)System.Math.Ceiling(((double)(b - a) / (double)stepSize)) - 1;
                for (uint i = 0; i < steps; i++)
                    yield return (float)(a +  i * stepSize);
                last = (float)(a +  steps * stepSize);
            }
            else
            {
                if (stepSize > 0)
                {
                    uint steps = (uint)System.Math.Ceiling(((double)(a - b) / (double)stepSize)) - 1;
                    for (uint i = 0; i < steps; i++)
                        yield return (float)(a - i * stepSize);
                    last = (float)(a - steps * stepSize);
                }
                else
                {
                    uint steps = (uint)System.Math.Ceiling(((double)(b - a) / (double)stepSize)) - 1;
                    for (uint i = 0; i < steps; i++)
                        yield return (float)(a + i * stepSize);
                    last = (float)(a + steps * stepSize);
                }
            }

            if (a < b)
            {
                yield return last > b ? b : last;
            }
            else
            {
                yield return last > a ? a : last;
            }
        }

        /// <summary>
        ///   Creates a range vector (like NumPy's arange function).
        /// </summary>
        /// 
        /// <param name="a">The inclusive lower bound of the range.</param>
        /// <param name="b">The exclusive upper bound of the range.</param>
        /// <param name="stepSize">The step size to be taken between elements. 
        ///   This parameter can be negative to create a decreasing range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static float[] Range(float a, float b, short stepSize)
        {
            if (a == b)
                return new float[] { };

            if (stepSize == 0)
                throw new ArgumentOutOfRangeException("stepSize", "stepSize must be different from zero.");

            float[] r;

            if (a < b)
            {
                if (stepSize < 0)
                    throw new ArgumentOutOfRangeException("stepSize", "If a < b, stepSize must be positive.");

                uint steps = (uint)System.Math.Ceiling(((float)(b - a) / (float)stepSize));

                r = new float[steps];
                for (uint i = 0; i < r.Length; i++)
                    r[i] = (float)(a +  i * stepSize);
            }
            else
            {
                if (stepSize > 0)
                {
                    uint steps = (uint)System.Math.Ceiling(((float)(a - b) / (float)stepSize));
                    r = new float[steps];
                    for (uint i = 0; i < r.Length; i++)
                        r[i] = (float)(a - i * stepSize);
                }
                else
                {
                    uint steps = (uint)System.Math.Ceiling(((float)(b - a) / (float)stepSize));
                    r = new float[steps];
                    for (uint i = 0; i < r.Length; i++)
                        r[i] = (float)(a + i * stepSize);
                }
            }

            if (a < b)
            {
                if (r[r.Length - 1] > b)
                    r[r.Length - 1] = b;
            }
            else
            {
                if (r[r.Length - 1] > a)
                    r[r.Length - 1] = a;
            }

            return r;
        }

        /// <summary>
        ///   Enumerates through a range (like Python's xrange function).
        /// </summary>
        /// 
        /// <param name="a">The inclusive lower bound of the range.</param>
        /// <param name="b">The exclusive upper bound of the range.</param>
        /// <param name="stepSize">The step size to be taken between elements. 
        ///   This parameter can be negative to create a decreasing range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static IEnumerable<float> EnumerableRange(float a, float b, short stepSize)
        {
            if (a == b)
                yield break;

            if (stepSize == 0)
                throw new ArgumentOutOfRangeException("stepSize", "stepSize must be different from zero.");

            float last;

            if (a < b)
            {
                if (stepSize < 0)
                    throw new ArgumentOutOfRangeException("stepSize", "If a < b, stepSize must be positive.");

                uint steps = (uint)System.Math.Ceiling(((float)(b - a) / (float)stepSize)) - 1;
                for (uint i = 0; i < steps; i++)
                    yield return (float)(a +  i * stepSize);
                last = (float)(a +  steps * stepSize);
            }
            else
            {
                if (stepSize > 0)
                {
                    uint steps = (uint)System.Math.Ceiling(((float)(a - b) / (float)stepSize)) - 1;
                    for (uint i = 0; i < steps; i++)
                        yield return (float)(a - i * stepSize);
                    last = (float)(a - steps * stepSize);
                }
                else
                {
                    uint steps = (uint)System.Math.Ceiling(((float)(b - a) / (float)stepSize)) - 1;
                    for (uint i = 0; i < steps; i++)
                        yield return (float)(a + i * stepSize);
                    last = (float)(a + steps * stepSize);
                }
            }

            if (a < b)
            {
                yield return last > b ? b : last;
            }
            else
            {
                yield return last > a ? a : last;
            }
        }

        /// <summary>
        ///   Creates a range vector (like NumPy's arange function).
        /// </summary>
        /// 
        /// <param name="a">The inclusive lower bound of the range.</param>
        /// <param name="b">The exclusive upper bound of the range.</param>
        /// <param name="stepSize">The step size to be taken between elements. 
        ///   This parameter can be negative to create a decreasing range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static float[] Range(float a, float b, byte stepSize)
        {
            if (a == b)
                return new float[] { };

            if (stepSize == 0)
                throw new ArgumentOutOfRangeException("stepSize", "stepSize must be different from zero.");

            float[] r;

            if (a < b)
            {
                if (stepSize < 0)
                    throw new ArgumentOutOfRangeException("stepSize", "If a < b, stepSize must be positive.");

                uint steps = (uint)System.Math.Ceiling(((float)(b - a) / (float)stepSize));

                r = new float[steps];
                for (uint i = 0; i < r.Length; i++)
                    r[i] = (float)(a +  i * stepSize);
            }
            else
            {
                if (stepSize > 0)
                {
                    uint steps = (uint)System.Math.Ceiling(((float)(a - b) / (float)stepSize));
                    r = new float[steps];
                    for (uint i = 0; i < r.Length; i++)
                        r[i] = (float)(a - i * stepSize);
                }
                else
                {
                    uint steps = (uint)System.Math.Ceiling(((float)(b - a) / (float)stepSize));
                    r = new float[steps];
                    for (uint i = 0; i < r.Length; i++)
                        r[i] = (float)(a + i * stepSize);
                }
            }

            if (a < b)
            {
                if (r[r.Length - 1] > b)
                    r[r.Length - 1] = b;
            }
            else
            {
                if (r[r.Length - 1] > a)
                    r[r.Length - 1] = a;
            }

            return r;
        }

        /// <summary>
        ///   Enumerates through a range (like Python's xrange function).
        /// </summary>
        /// 
        /// <param name="a">The inclusive lower bound of the range.</param>
        /// <param name="b">The exclusive upper bound of the range.</param>
        /// <param name="stepSize">The step size to be taken between elements. 
        ///   This parameter can be negative to create a decreasing range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static IEnumerable<float> EnumerableRange(float a, float b, byte stepSize)
        {
            if (a == b)
                yield break;

            if (stepSize == 0)
                throw new ArgumentOutOfRangeException("stepSize", "stepSize must be different from zero.");

            float last;

            if (a < b)
            {
                if (stepSize < 0)
                    throw new ArgumentOutOfRangeException("stepSize", "If a < b, stepSize must be positive.");

                uint steps = (uint)System.Math.Ceiling(((float)(b - a) / (float)stepSize)) - 1;
                for (uint i = 0; i < steps; i++)
                    yield return (float)(a +  i * stepSize);
                last = (float)(a +  steps * stepSize);
            }
            else
            {
                if (stepSize > 0)
                {
                    uint steps = (uint)System.Math.Ceiling(((float)(a - b) / (float)stepSize)) - 1;
                    for (uint i = 0; i < steps; i++)
                        yield return (float)(a - i * stepSize);
                    last = (float)(a - steps * stepSize);
                }
                else
                {
                    uint steps = (uint)System.Math.Ceiling(((float)(b - a) / (float)stepSize)) - 1;
                    for (uint i = 0; i < steps; i++)
                        yield return (float)(a + i * stepSize);
                    last = (float)(a + steps * stepSize);
                }
            }

            if (a < b)
            {
                yield return last > b ? b : last;
            }
            else
            {
                yield return last > a ? a : last;
            }
        }

        /// <summary>
        ///   Creates a range vector (like NumPy's arange function).
        /// </summary>
        /// 
        /// <param name="a">The inclusive lower bound of the range.</param>
        /// <param name="b">The exclusive upper bound of the range.</param>
        /// <param name="stepSize">The step size to be taken between elements. 
        ///   This parameter can be negative to create a decreasing range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static float[] Range(float a, float b, sbyte stepSize)
        {
            if (a == b)
                return new float[] { };

            if (stepSize == 0)
                throw new ArgumentOutOfRangeException("stepSize", "stepSize must be different from zero.");

            float[] r;

            if (a < b)
            {
                if (stepSize < 0)
                    throw new ArgumentOutOfRangeException("stepSize", "If a < b, stepSize must be positive.");

                uint steps = (uint)System.Math.Ceiling(((float)(b - a) / (float)stepSize));

                r = new float[steps];
                for (uint i = 0; i < r.Length; i++)
                    r[i] = (float)(a +  i * stepSize);
            }
            else
            {
                if (stepSize > 0)
                {
                    uint steps = (uint)System.Math.Ceiling(((float)(a - b) / (float)stepSize));
                    r = new float[steps];
                    for (uint i = 0; i < r.Length; i++)
                        r[i] = (float)(a - i * stepSize);
                }
                else
                {
                    uint steps = (uint)System.Math.Ceiling(((float)(b - a) / (float)stepSize));
                    r = new float[steps];
                    for (uint i = 0; i < r.Length; i++)
                        r[i] = (float)(a + i * stepSize);
                }
            }

            if (a < b)
            {
                if (r[r.Length - 1] > b)
                    r[r.Length - 1] = b;
            }
            else
            {
                if (r[r.Length - 1] > a)
                    r[r.Length - 1] = a;
            }

            return r;
        }

        /// <summary>
        ///   Enumerates through a range (like Python's xrange function).
        /// </summary>
        /// 
        /// <param name="a">The inclusive lower bound of the range.</param>
        /// <param name="b">The exclusive upper bound of the range.</param>
        /// <param name="stepSize">The step size to be taken between elements. 
        ///   This parameter can be negative to create a decreasing range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static IEnumerable<float> EnumerableRange(float a, float b, sbyte stepSize)
        {
            if (a == b)
                yield break;

            if (stepSize == 0)
                throw new ArgumentOutOfRangeException("stepSize", "stepSize must be different from zero.");

            float last;

            if (a < b)
            {
                if (stepSize < 0)
                    throw new ArgumentOutOfRangeException("stepSize", "If a < b, stepSize must be positive.");

                uint steps = (uint)System.Math.Ceiling(((float)(b - a) / (float)stepSize)) - 1;
                for (uint i = 0; i < steps; i++)
                    yield return (float)(a +  i * stepSize);
                last = (float)(a +  steps * stepSize);
            }
            else
            {
                if (stepSize > 0)
                {
                    uint steps = (uint)System.Math.Ceiling(((float)(a - b) / (float)stepSize)) - 1;
                    for (uint i = 0; i < steps; i++)
                        yield return (float)(a - i * stepSize);
                    last = (float)(a - steps * stepSize);
                }
                else
                {
                    uint steps = (uint)System.Math.Ceiling(((float)(b - a) / (float)stepSize)) - 1;
                    for (uint i = 0; i < steps; i++)
                        yield return (float)(a + i * stepSize);
                    last = (float)(a + steps * stepSize);
                }
            }

            if (a < b)
            {
                yield return last > b ? b : last;
            }
            else
            {
                yield return last > a ? a : last;
            }
        }

        /// <summary>
        ///   Creates a range vector (like NumPy's arange function).
        /// </summary>
        /// 
        /// <param name="a">The inclusive lower bound of the range.</param>
        /// <param name="b">The exclusive upper bound of the range.</param>
        /// <param name="stepSize">The step size to be taken between elements. 
        ///   This parameter can be negative to create a decreasing range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static float[] Range(float a, float b, long stepSize)
        {
            if (a == b)
                return new float[] { };

            if (stepSize == 0)
                throw new ArgumentOutOfRangeException("stepSize", "stepSize must be different from zero.");

            float[] r;

            if (a < b)
            {
                if (stepSize < 0)
                    throw new ArgumentOutOfRangeException("stepSize", "If a < b, stepSize must be positive.");

                uint steps = (uint)System.Math.Ceiling(((float)(b - a) / (float)stepSize));

                r = new float[steps];
                for (uint i = 0; i < r.Length; i++)
                    r[i] = (float)(a +  i * stepSize);
            }
            else
            {
                if (stepSize > 0)
                {
                    uint steps = (uint)System.Math.Ceiling(((float)(a - b) / (float)stepSize));
                    r = new float[steps];
                    for (uint i = 0; i < r.Length; i++)
                        r[i] = (float)(a - i * stepSize);
                }
                else
                {
                    uint steps = (uint)System.Math.Ceiling(((float)(b - a) / (float)stepSize));
                    r = new float[steps];
                    for (uint i = 0; i < r.Length; i++)
                        r[i] = (float)(a + i * stepSize);
                }
            }

            if (a < b)
            {
                if (r[r.Length - 1] > b)
                    r[r.Length - 1] = b;
            }
            else
            {
                if (r[r.Length - 1] > a)
                    r[r.Length - 1] = a;
            }

            return r;
        }

        /// <summary>
        ///   Enumerates through a range (like Python's xrange function).
        /// </summary>
        /// 
        /// <param name="a">The inclusive lower bound of the range.</param>
        /// <param name="b">The exclusive upper bound of the range.</param>
        /// <param name="stepSize">The step size to be taken between elements. 
        ///   This parameter can be negative to create a decreasing range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static IEnumerable<float> EnumerableRange(float a, float b, long stepSize)
        {
            if (a == b)
                yield break;

            if (stepSize == 0)
                throw new ArgumentOutOfRangeException("stepSize", "stepSize must be different from zero.");

            float last;

            if (a < b)
            {
                if (stepSize < 0)
                    throw new ArgumentOutOfRangeException("stepSize", "If a < b, stepSize must be positive.");

                uint steps = (uint)System.Math.Ceiling(((float)(b - a) / (float)stepSize)) - 1;
                for (uint i = 0; i < steps; i++)
                    yield return (float)(a +  i * stepSize);
                last = (float)(a +  steps * stepSize);
            }
            else
            {
                if (stepSize > 0)
                {
                    uint steps = (uint)System.Math.Ceiling(((float)(a - b) / (float)stepSize)) - 1;
                    for (uint i = 0; i < steps; i++)
                        yield return (float)(a - i * stepSize);
                    last = (float)(a - steps * stepSize);
                }
                else
                {
                    uint steps = (uint)System.Math.Ceiling(((float)(b - a) / (float)stepSize)) - 1;
                    for (uint i = 0; i < steps; i++)
                        yield return (float)(a + i * stepSize);
                    last = (float)(a + steps * stepSize);
                }
            }

            if (a < b)
            {
                yield return last > b ? b : last;
            }
            else
            {
                yield return last > a ? a : last;
            }
        }

        /// <summary>
        ///   Creates a range vector (like NumPy's arange function).
        /// </summary>
        /// 
        /// <param name="a">The inclusive lower bound of the range.</param>
        /// <param name="b">The exclusive upper bound of the range.</param>
        /// <param name="stepSize">The step size to be taken between elements. 
        ///   This parameter can be negative to create a decreasing range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static float[] Range(float a, float b, ulong stepSize)
        {
            if (a == b)
                return new float[] { };

            if (stepSize == 0)
                throw new ArgumentOutOfRangeException("stepSize", "stepSize must be different from zero.");

            float[] r;

            if (a < b)
            {
                if (stepSize < 0)
                    throw new ArgumentOutOfRangeException("stepSize", "If a < b, stepSize must be positive.");

                uint steps = (uint)System.Math.Ceiling(((float)(b - a) / (float)stepSize));

                r = new float[steps];
                for (uint i = 0; i < r.Length; i++)
                    r[i] = (float)(a +  i * stepSize);
            }
            else
            {
                if (stepSize > 0)
                {
                    uint steps = (uint)System.Math.Ceiling(((float)(a - b) / (float)stepSize));
                    r = new float[steps];
                    for (uint i = 0; i < r.Length; i++)
                        r[i] = (float)(a - i * stepSize);
                }
                else
                {
                    uint steps = (uint)System.Math.Ceiling(((float)(b - a) / (float)stepSize));
                    r = new float[steps];
                    for (uint i = 0; i < r.Length; i++)
                        r[i] = (float)(a + i * stepSize);
                }
            }

            if (a < b)
            {
                if (r[r.Length - 1] > b)
                    r[r.Length - 1] = b;
            }
            else
            {
                if (r[r.Length - 1] > a)
                    r[r.Length - 1] = a;
            }

            return r;
        }

        /// <summary>
        ///   Enumerates through a range (like Python's xrange function).
        /// </summary>
        /// 
        /// <param name="a">The inclusive lower bound of the range.</param>
        /// <param name="b">The exclusive upper bound of the range.</param>
        /// <param name="stepSize">The step size to be taken between elements. 
        ///   This parameter can be negative to create a decreasing range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static IEnumerable<float> EnumerableRange(float a, float b, ulong stepSize)
        {
            if (a == b)
                yield break;

            if (stepSize == 0)
                throw new ArgumentOutOfRangeException("stepSize", "stepSize must be different from zero.");

            float last;

            if (a < b)
            {
                if (stepSize < 0)
                    throw new ArgumentOutOfRangeException("stepSize", "If a < b, stepSize must be positive.");

                uint steps = (uint)System.Math.Ceiling(((float)(b - a) / (float)stepSize)) - 1;
                for (uint i = 0; i < steps; i++)
                    yield return (float)(a +  i * stepSize);
                last = (float)(a +  steps * stepSize);
            }
            else
            {
                if (stepSize > 0)
                {
                    uint steps = (uint)System.Math.Ceiling(((float)(a - b) / (float)stepSize)) - 1;
                    for (uint i = 0; i < steps; i++)
                        yield return (float)(a - i * stepSize);
                    last = (float)(a - steps * stepSize);
                }
                else
                {
                    uint steps = (uint)System.Math.Ceiling(((float)(b - a) / (float)stepSize)) - 1;
                    for (uint i = 0; i < steps; i++)
                        yield return (float)(a + i * stepSize);
                    last = (float)(a + steps * stepSize);
                }
            }

            if (a < b)
            {
                yield return last > b ? b : last;
            }
            else
            {
                yield return last > a ? a : last;
            }
        }

        /// <summary>
        ///   Creates a range vector (like NumPy's arange function).
        /// </summary>
        /// 
        /// <param name="a">The inclusive lower bound of the range.</param>
        /// <param name="b">The exclusive upper bound of the range.</param>
        /// <param name="stepSize">The step size to be taken between elements. 
        ///   This parameter can be negative to create a decreasing range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static float[] Range(float a, float b, ushort stepSize)
        {
            if (a == b)
                return new float[] { };

            if (stepSize == 0)
                throw new ArgumentOutOfRangeException("stepSize", "stepSize must be different from zero.");

            float[] r;

            if (a < b)
            {
                if (stepSize < 0)
                    throw new ArgumentOutOfRangeException("stepSize", "If a < b, stepSize must be positive.");

                uint steps = (uint)System.Math.Ceiling(((float)(b - a) / (float)stepSize));

                r = new float[steps];
                for (uint i = 0; i < r.Length; i++)
                    r[i] = (float)(a +  i * stepSize);
            }
            else
            {
                if (stepSize > 0)
                {
                    uint steps = (uint)System.Math.Ceiling(((float)(a - b) / (float)stepSize));
                    r = new float[steps];
                    for (uint i = 0; i < r.Length; i++)
                        r[i] = (float)(a - i * stepSize);
                }
                else
                {
                    uint steps = (uint)System.Math.Ceiling(((float)(b - a) / (float)stepSize));
                    r = new float[steps];
                    for (uint i = 0; i < r.Length; i++)
                        r[i] = (float)(a + i * stepSize);
                }
            }

            if (a < b)
            {
                if (r[r.Length - 1] > b)
                    r[r.Length - 1] = b;
            }
            else
            {
                if (r[r.Length - 1] > a)
                    r[r.Length - 1] = a;
            }

            return r;
        }

        /// <summary>
        ///   Enumerates through a range (like Python's xrange function).
        /// </summary>
        /// 
        /// <param name="a">The inclusive lower bound of the range.</param>
        /// <param name="b">The exclusive upper bound of the range.</param>
        /// <param name="stepSize">The step size to be taken between elements. 
        ///   This parameter can be negative to create a decreasing range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static IEnumerable<float> EnumerableRange(float a, float b, ushort stepSize)
        {
            if (a == b)
                yield break;

            if (stepSize == 0)
                throw new ArgumentOutOfRangeException("stepSize", "stepSize must be different from zero.");

            float last;

            if (a < b)
            {
                if (stepSize < 0)
                    throw new ArgumentOutOfRangeException("stepSize", "If a < b, stepSize must be positive.");

                uint steps = (uint)System.Math.Ceiling(((float)(b - a) / (float)stepSize)) - 1;
                for (uint i = 0; i < steps; i++)
                    yield return (float)(a +  i * stepSize);
                last = (float)(a +  steps * stepSize);
            }
            else
            {
                if (stepSize > 0)
                {
                    uint steps = (uint)System.Math.Ceiling(((float)(a - b) / (float)stepSize)) - 1;
                    for (uint i = 0; i < steps; i++)
                        yield return (float)(a - i * stepSize);
                    last = (float)(a - steps * stepSize);
                }
                else
                {
                    uint steps = (uint)System.Math.Ceiling(((float)(b - a) / (float)stepSize)) - 1;
                    for (uint i = 0; i < steps; i++)
                        yield return (float)(a + i * stepSize);
                    last = (float)(a + steps * stepSize);
                }
            }

            if (a < b)
            {
                yield return last > b ? b : last;
            }
            else
            {
                yield return last > a ? a : last;
            }
        }

        /// <summary>
        ///   Creates a range vector (like NumPy's arange function).
        /// </summary>
        /// 
        /// <param name="n">The exclusive upper bound of the range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static double[] Range(double n)
        {
            double[] r = new double[(int)n]; 
            for (int i = 0; i < r.Length; i++)
                r[i] = (double)i;
            return r;
        }

        /// <summary>
        ///   Creates a range vector (like NumPy's arange function).
        /// </summary>
        ///
        /// <param name="a">The inclusive lower bound of the range.</param>
        /// <param name="b">The exclusive upper bound of the range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static double[] Range(double a, double b)
        {
            if (a == b)
                return new double[] { };

            double[] r;

            if (b > a)
            {
                r = new double[(int)(b - a)];
                for (int i = 0; i < r.Length; i++)
                    r[i] = (double)(a++);
            }
            else
            {
                r = new double[(int)(a - b)];
                for (int i = 0; i < r.Length; i++)
                    r[i] = (double)(a--);
            }

            return r;
        }

        /// <summary>
        ///   Enumerates through a range (like Python's xrange function).
        /// </summary>
        /// 
        /// <param name="n">The exclusive upper bound of the range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static IEnumerable<double> EnumerableRange(double n)
        {
            for (double i = 0; i < n; i++)
                yield return (double)i;
        }

        /// <summary>
        ///   Enumerates through a range (like Python's xrange).
        /// </summary>
        /// 
        /// <param name="a">The inclusive lower bound of the range.</param>
        /// <param name="b">The exclusive upper bound of the range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static IEnumerable<double> EnumerableRange(double a, double b)
        {
            if (a == b)
                yield break;

            if (b > a)
            {
                int n = (int)(b - a);
                for (int i = 0; i < n; i++)
                    yield return (double)(a++);
            }
            else
            {
                int n = (int)(a - b);
                for (int i = 0; i < n; i++)
                    yield return (double)(a--);
            }
        }


        /// <summary>
        ///   Creates a range vector (like NumPy's arange function).
        /// </summary>
        /// 
        /// <param name="a">The inclusive lower bound of the range.</param>
        /// <param name="b">The exclusive upper bound of the range.</param>
        /// <param name="stepSize">The step size to be taken between elements. 
        ///   This parameter can be negative to create a decreasing range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static double[] Range(double a, double b, int stepSize)
        {
            if (a == b)
                return new double[] { };

            if (stepSize == 0)
                throw new ArgumentOutOfRangeException("stepSize", "stepSize must be different from zero.");

            double[] r;

            if (a < b)
            {
                if (stepSize < 0)
                    throw new ArgumentOutOfRangeException("stepSize", "If a < b, stepSize must be positive.");

                uint steps = (uint)System.Math.Ceiling(((double)(b - a) / (double)stepSize));

                r = new double[steps];
                for (uint i = 0; i < r.Length; i++)
                    r[i] = (double)(a +  i * stepSize);
            }
            else
            {
                if (stepSize > 0)
                {
                    uint steps = (uint)System.Math.Ceiling(((double)(a - b) / (double)stepSize));
                    r = new double[steps];
                    for (uint i = 0; i < r.Length; i++)
                        r[i] = (double)(a - i * stepSize);
                }
                else
                {
                    uint steps = (uint)System.Math.Ceiling(((double)(b - a) / (double)stepSize));
                    r = new double[steps];
                    for (uint i = 0; i < r.Length; i++)
                        r[i] = (double)(a + i * stepSize);
                }
            }

            if (a < b)
            {
                if (r[r.Length - 1] > b)
                    r[r.Length - 1] = b;
            }
            else
            {
                if (r[r.Length - 1] > a)
                    r[r.Length - 1] = a;
            }

            return r;
        }

        /// <summary>
        ///   Enumerates through a range (like Python's xrange function).
        /// </summary>
        /// 
        /// <param name="a">The inclusive lower bound of the range.</param>
        /// <param name="b">The exclusive upper bound of the range.</param>
        /// <param name="stepSize">The step size to be taken between elements. 
        ///   This parameter can be negative to create a decreasing range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static IEnumerable<double> EnumerableRange(double a, double b, int stepSize)
        {
            if (a == b)
                yield break;

            if (stepSize == 0)
                throw new ArgumentOutOfRangeException("stepSize", "stepSize must be different from zero.");

            double last;

            if (a < b)
            {
                if (stepSize < 0)
                    throw new ArgumentOutOfRangeException("stepSize", "If a < b, stepSize must be positive.");

                uint steps = (uint)System.Math.Ceiling(((double)(b - a) / (double)stepSize)) - 1;
                for (uint i = 0; i < steps; i++)
                    yield return (double)(a +  i * stepSize);
                last = (double)(a +  steps * stepSize);
            }
            else
            {
                if (stepSize > 0)
                {
                    uint steps = (uint)System.Math.Ceiling(((double)(a - b) / (double)stepSize)) - 1;
                    for (uint i = 0; i < steps; i++)
                        yield return (double)(a - i * stepSize);
                    last = (double)(a - steps * stepSize);
                }
                else
                {
                    uint steps = (uint)System.Math.Ceiling(((double)(b - a) / (double)stepSize)) - 1;
                    for (uint i = 0; i < steps; i++)
                        yield return (double)(a + i * stepSize);
                    last = (double)(a + steps * stepSize);
                }
            }

            if (a < b)
            {
                yield return last > b ? b : last;
            }
            else
            {
                yield return last > a ? a : last;
            }
        }

        /// <summary>
        ///   Creates a range vector (like NumPy's arange function).
        /// </summary>
        /// 
        /// <param name="a">The inclusive lower bound of the range.</param>
        /// <param name="b">The exclusive upper bound of the range.</param>
        /// <param name="stepSize">The step size to be taken between elements. 
        ///   This parameter can be negative to create a decreasing range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static double[] Range(double a, double b, double stepSize)
        {
            if (a == b)
                return new double[] { };

            if (stepSize == 0)
                throw new ArgumentOutOfRangeException("stepSize", "stepSize must be different from zero.");

            double[] r;

            if (a < b)
            {
                if (stepSize < 0)
                    throw new ArgumentOutOfRangeException("stepSize", "If a < b, stepSize must be positive.");

                uint steps = (uint)System.Math.Ceiling(((double)(b - a) / (double)stepSize));

                r = new double[steps];
                for (uint i = 0; i < r.Length; i++)
                    r[i] = (double)(a +  i * stepSize);
            }
            else
            {
                if (stepSize > 0)
                {
                    uint steps = (uint)System.Math.Ceiling(((double)(a - b) / (double)stepSize));
                    r = new double[steps];
                    for (uint i = 0; i < r.Length; i++)
                        r[i] = (double)(a - i * stepSize);
                }
                else
                {
                    uint steps = (uint)System.Math.Ceiling(((double)(b - a) / (double)stepSize));
                    r = new double[steps];
                    for (uint i = 0; i < r.Length; i++)
                        r[i] = (double)(a + i * stepSize);
                }
            }

            if (a < b)
            {
                if (r[r.Length - 1] > b)
                    r[r.Length - 1] = b;
            }
            else
            {
                if (r[r.Length - 1] > a)
                    r[r.Length - 1] = a;
            }

            return r;
        }

        /// <summary>
        ///   Enumerates through a range (like Python's xrange function).
        /// </summary>
        /// 
        /// <param name="a">The inclusive lower bound of the range.</param>
        /// <param name="b">The exclusive upper bound of the range.</param>
        /// <param name="stepSize">The step size to be taken between elements. 
        ///   This parameter can be negative to create a decreasing range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static IEnumerable<double> EnumerableRange(double a, double b, double stepSize)
        {
            if (a == b)
                yield break;

            if (stepSize == 0)
                throw new ArgumentOutOfRangeException("stepSize", "stepSize must be different from zero.");

            double last;

            if (a < b)
            {
                if (stepSize < 0)
                    throw new ArgumentOutOfRangeException("stepSize", "If a < b, stepSize must be positive.");

                uint steps = (uint)System.Math.Ceiling(((double)(b - a) / (double)stepSize)) - 1;
                for (uint i = 0; i < steps; i++)
                    yield return (double)(a +  i * stepSize);
                last = (double)(a +  steps * stepSize);
            }
            else
            {
                if (stepSize > 0)
                {
                    uint steps = (uint)System.Math.Ceiling(((double)(a - b) / (double)stepSize)) - 1;
                    for (uint i = 0; i < steps; i++)
                        yield return (double)(a - i * stepSize);
                    last = (double)(a - steps * stepSize);
                }
                else
                {
                    uint steps = (uint)System.Math.Ceiling(((double)(b - a) / (double)stepSize)) - 1;
                    for (uint i = 0; i < steps; i++)
                        yield return (double)(a + i * stepSize);
                    last = (double)(a + steps * stepSize);
                }
            }

            if (a < b)
            {
                yield return last > b ? b : last;
            }
            else
            {
                yield return last > a ? a : last;
            }
        }

        /// <summary>
        ///   Creates a range vector (like NumPy's arange function).
        /// </summary>
        /// 
        /// <param name="a">The inclusive lower bound of the range.</param>
        /// <param name="b">The exclusive upper bound of the range.</param>
        /// <param name="stepSize">The step size to be taken between elements. 
        ///   This parameter can be negative to create a decreasing range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static double[] Range(double a, double b, short stepSize)
        {
            if (a == b)
                return new double[] { };

            if (stepSize == 0)
                throw new ArgumentOutOfRangeException("stepSize", "stepSize must be different from zero.");

            double[] r;

            if (a < b)
            {
                if (stepSize < 0)
                    throw new ArgumentOutOfRangeException("stepSize", "If a < b, stepSize must be positive.");

                uint steps = (uint)System.Math.Ceiling(((double)(b - a) / (double)stepSize));

                r = new double[steps];
                for (uint i = 0; i < r.Length; i++)
                    r[i] = (double)(a +  i * stepSize);
            }
            else
            {
                if (stepSize > 0)
                {
                    uint steps = (uint)System.Math.Ceiling(((double)(a - b) / (double)stepSize));
                    r = new double[steps];
                    for (uint i = 0; i < r.Length; i++)
                        r[i] = (double)(a - i * stepSize);
                }
                else
                {
                    uint steps = (uint)System.Math.Ceiling(((double)(b - a) / (double)stepSize));
                    r = new double[steps];
                    for (uint i = 0; i < r.Length; i++)
                        r[i] = (double)(a + i * stepSize);
                }
            }

            if (a < b)
            {
                if (r[r.Length - 1] > b)
                    r[r.Length - 1] = b;
            }
            else
            {
                if (r[r.Length - 1] > a)
                    r[r.Length - 1] = a;
            }

            return r;
        }

        /// <summary>
        ///   Enumerates through a range (like Python's xrange function).
        /// </summary>
        /// 
        /// <param name="a">The inclusive lower bound of the range.</param>
        /// <param name="b">The exclusive upper bound of the range.</param>
        /// <param name="stepSize">The step size to be taken between elements. 
        ///   This parameter can be negative to create a decreasing range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static IEnumerable<double> EnumerableRange(double a, double b, short stepSize)
        {
            if (a == b)
                yield break;

            if (stepSize == 0)
                throw new ArgumentOutOfRangeException("stepSize", "stepSize must be different from zero.");

            double last;

            if (a < b)
            {
                if (stepSize < 0)
                    throw new ArgumentOutOfRangeException("stepSize", "If a < b, stepSize must be positive.");

                uint steps = (uint)System.Math.Ceiling(((double)(b - a) / (double)stepSize)) - 1;
                for (uint i = 0; i < steps; i++)
                    yield return (double)(a +  i * stepSize);
                last = (double)(a +  steps * stepSize);
            }
            else
            {
                if (stepSize > 0)
                {
                    uint steps = (uint)System.Math.Ceiling(((double)(a - b) / (double)stepSize)) - 1;
                    for (uint i = 0; i < steps; i++)
                        yield return (double)(a - i * stepSize);
                    last = (double)(a - steps * stepSize);
                }
                else
                {
                    uint steps = (uint)System.Math.Ceiling(((double)(b - a) / (double)stepSize)) - 1;
                    for (uint i = 0; i < steps; i++)
                        yield return (double)(a + i * stepSize);
                    last = (double)(a + steps * stepSize);
                }
            }

            if (a < b)
            {
                yield return last > b ? b : last;
            }
            else
            {
                yield return last > a ? a : last;
            }
        }

        /// <summary>
        ///   Creates a range vector (like NumPy's arange function).
        /// </summary>
        /// 
        /// <param name="a">The inclusive lower bound of the range.</param>
        /// <param name="b">The exclusive upper bound of the range.</param>
        /// <param name="stepSize">The step size to be taken between elements. 
        ///   This parameter can be negative to create a decreasing range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static double[] Range(double a, double b, byte stepSize)
        {
            if (a == b)
                return new double[] { };

            if (stepSize == 0)
                throw new ArgumentOutOfRangeException("stepSize", "stepSize must be different from zero.");

            double[] r;

            if (a < b)
            {
                if (stepSize < 0)
                    throw new ArgumentOutOfRangeException("stepSize", "If a < b, stepSize must be positive.");

                uint steps = (uint)System.Math.Ceiling(((double)(b - a) / (double)stepSize));

                r = new double[steps];
                for (uint i = 0; i < r.Length; i++)
                    r[i] = (double)(a +  i * stepSize);
            }
            else
            {
                if (stepSize > 0)
                {
                    uint steps = (uint)System.Math.Ceiling(((double)(a - b) / (double)stepSize));
                    r = new double[steps];
                    for (uint i = 0; i < r.Length; i++)
                        r[i] = (double)(a - i * stepSize);
                }
                else
                {
                    uint steps = (uint)System.Math.Ceiling(((double)(b - a) / (double)stepSize));
                    r = new double[steps];
                    for (uint i = 0; i < r.Length; i++)
                        r[i] = (double)(a + i * stepSize);
                }
            }

            if (a < b)
            {
                if (r[r.Length - 1] > b)
                    r[r.Length - 1] = b;
            }
            else
            {
                if (r[r.Length - 1] > a)
                    r[r.Length - 1] = a;
            }

            return r;
        }

        /// <summary>
        ///   Enumerates through a range (like Python's xrange function).
        /// </summary>
        /// 
        /// <param name="a">The inclusive lower bound of the range.</param>
        /// <param name="b">The exclusive upper bound of the range.</param>
        /// <param name="stepSize">The step size to be taken between elements. 
        ///   This parameter can be negative to create a decreasing range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static IEnumerable<double> EnumerableRange(double a, double b, byte stepSize)
        {
            if (a == b)
                yield break;

            if (stepSize == 0)
                throw new ArgumentOutOfRangeException("stepSize", "stepSize must be different from zero.");

            double last;

            if (a < b)
            {
                if (stepSize < 0)
                    throw new ArgumentOutOfRangeException("stepSize", "If a < b, stepSize must be positive.");

                uint steps = (uint)System.Math.Ceiling(((double)(b - a) / (double)stepSize)) - 1;
                for (uint i = 0; i < steps; i++)
                    yield return (double)(a +  i * stepSize);
                last = (double)(a +  steps * stepSize);
            }
            else
            {
                if (stepSize > 0)
                {
                    uint steps = (uint)System.Math.Ceiling(((double)(a - b) / (double)stepSize)) - 1;
                    for (uint i = 0; i < steps; i++)
                        yield return (double)(a - i * stepSize);
                    last = (double)(a - steps * stepSize);
                }
                else
                {
                    uint steps = (uint)System.Math.Ceiling(((double)(b - a) / (double)stepSize)) - 1;
                    for (uint i = 0; i < steps; i++)
                        yield return (double)(a + i * stepSize);
                    last = (double)(a + steps * stepSize);
                }
            }

            if (a < b)
            {
                yield return last > b ? b : last;
            }
            else
            {
                yield return last > a ? a : last;
            }
        }

        /// <summary>
        ///   Creates a range vector (like NumPy's arange function).
        /// </summary>
        /// 
        /// <param name="a">The inclusive lower bound of the range.</param>
        /// <param name="b">The exclusive upper bound of the range.</param>
        /// <param name="stepSize">The step size to be taken between elements. 
        ///   This parameter can be negative to create a decreasing range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static double[] Range(double a, double b, sbyte stepSize)
        {
            if (a == b)
                return new double[] { };

            if (stepSize == 0)
                throw new ArgumentOutOfRangeException("stepSize", "stepSize must be different from zero.");

            double[] r;

            if (a < b)
            {
                if (stepSize < 0)
                    throw new ArgumentOutOfRangeException("stepSize", "If a < b, stepSize must be positive.");

                uint steps = (uint)System.Math.Ceiling(((double)(b - a) / (double)stepSize));

                r = new double[steps];
                for (uint i = 0; i < r.Length; i++)
                    r[i] = (double)(a +  i * stepSize);
            }
            else
            {
                if (stepSize > 0)
                {
                    uint steps = (uint)System.Math.Ceiling(((double)(a - b) / (double)stepSize));
                    r = new double[steps];
                    for (uint i = 0; i < r.Length; i++)
                        r[i] = (double)(a - i * stepSize);
                }
                else
                {
                    uint steps = (uint)System.Math.Ceiling(((double)(b - a) / (double)stepSize));
                    r = new double[steps];
                    for (uint i = 0; i < r.Length; i++)
                        r[i] = (double)(a + i * stepSize);
                }
            }

            if (a < b)
            {
                if (r[r.Length - 1] > b)
                    r[r.Length - 1] = b;
            }
            else
            {
                if (r[r.Length - 1] > a)
                    r[r.Length - 1] = a;
            }

            return r;
        }

        /// <summary>
        ///   Enumerates through a range (like Python's xrange function).
        /// </summary>
        /// 
        /// <param name="a">The inclusive lower bound of the range.</param>
        /// <param name="b">The exclusive upper bound of the range.</param>
        /// <param name="stepSize">The step size to be taken between elements. 
        ///   This parameter can be negative to create a decreasing range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static IEnumerable<double> EnumerableRange(double a, double b, sbyte stepSize)
        {
            if (a == b)
                yield break;

            if (stepSize == 0)
                throw new ArgumentOutOfRangeException("stepSize", "stepSize must be different from zero.");

            double last;

            if (a < b)
            {
                if (stepSize < 0)
                    throw new ArgumentOutOfRangeException("stepSize", "If a < b, stepSize must be positive.");

                uint steps = (uint)System.Math.Ceiling(((double)(b - a) / (double)stepSize)) - 1;
                for (uint i = 0; i < steps; i++)
                    yield return (double)(a +  i * stepSize);
                last = (double)(a +  steps * stepSize);
            }
            else
            {
                if (stepSize > 0)
                {
                    uint steps = (uint)System.Math.Ceiling(((double)(a - b) / (double)stepSize)) - 1;
                    for (uint i = 0; i < steps; i++)
                        yield return (double)(a - i * stepSize);
                    last = (double)(a - steps * stepSize);
                }
                else
                {
                    uint steps = (uint)System.Math.Ceiling(((double)(b - a) / (double)stepSize)) - 1;
                    for (uint i = 0; i < steps; i++)
                        yield return (double)(a + i * stepSize);
                    last = (double)(a + steps * stepSize);
                }
            }

            if (a < b)
            {
                yield return last > b ? b : last;
            }
            else
            {
                yield return last > a ? a : last;
            }
        }

        /// <summary>
        ///   Creates a range vector (like NumPy's arange function).
        /// </summary>
        /// 
        /// <param name="a">The inclusive lower bound of the range.</param>
        /// <param name="b">The exclusive upper bound of the range.</param>
        /// <param name="stepSize">The step size to be taken between elements. 
        ///   This parameter can be negative to create a decreasing range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static double[] Range(double a, double b, long stepSize)
        {
            if (a == b)
                return new double[] { };

            if (stepSize == 0)
                throw new ArgumentOutOfRangeException("stepSize", "stepSize must be different from zero.");

            double[] r;

            if (a < b)
            {
                if (stepSize < 0)
                    throw new ArgumentOutOfRangeException("stepSize", "If a < b, stepSize must be positive.");

                uint steps = (uint)System.Math.Ceiling(((double)(b - a) / (double)stepSize));

                r = new double[steps];
                for (uint i = 0; i < r.Length; i++)
                    r[i] = (double)(a +  i * stepSize);
            }
            else
            {
                if (stepSize > 0)
                {
                    uint steps = (uint)System.Math.Ceiling(((double)(a - b) / (double)stepSize));
                    r = new double[steps];
                    for (uint i = 0; i < r.Length; i++)
                        r[i] = (double)(a - i * stepSize);
                }
                else
                {
                    uint steps = (uint)System.Math.Ceiling(((double)(b - a) / (double)stepSize));
                    r = new double[steps];
                    for (uint i = 0; i < r.Length; i++)
                        r[i] = (double)(a + i * stepSize);
                }
            }

            if (a < b)
            {
                if (r[r.Length - 1] > b)
                    r[r.Length - 1] = b;
            }
            else
            {
                if (r[r.Length - 1] > a)
                    r[r.Length - 1] = a;
            }

            return r;
        }

        /// <summary>
        ///   Enumerates through a range (like Python's xrange function).
        /// </summary>
        /// 
        /// <param name="a">The inclusive lower bound of the range.</param>
        /// <param name="b">The exclusive upper bound of the range.</param>
        /// <param name="stepSize">The step size to be taken between elements. 
        ///   This parameter can be negative to create a decreasing range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static IEnumerable<double> EnumerableRange(double a, double b, long stepSize)
        {
            if (a == b)
                yield break;

            if (stepSize == 0)
                throw new ArgumentOutOfRangeException("stepSize", "stepSize must be different from zero.");

            double last;

            if (a < b)
            {
                if (stepSize < 0)
                    throw new ArgumentOutOfRangeException("stepSize", "If a < b, stepSize must be positive.");

                uint steps = (uint)System.Math.Ceiling(((double)(b - a) / (double)stepSize)) - 1;
                for (uint i = 0; i < steps; i++)
                    yield return (double)(a +  i * stepSize);
                last = (double)(a +  steps * stepSize);
            }
            else
            {
                if (stepSize > 0)
                {
                    uint steps = (uint)System.Math.Ceiling(((double)(a - b) / (double)stepSize)) - 1;
                    for (uint i = 0; i < steps; i++)
                        yield return (double)(a - i * stepSize);
                    last = (double)(a - steps * stepSize);
                }
                else
                {
                    uint steps = (uint)System.Math.Ceiling(((double)(b - a) / (double)stepSize)) - 1;
                    for (uint i = 0; i < steps; i++)
                        yield return (double)(a + i * stepSize);
                    last = (double)(a + steps * stepSize);
                }
            }

            if (a < b)
            {
                yield return last > b ? b : last;
            }
            else
            {
                yield return last > a ? a : last;
            }
        }

        /// <summary>
        ///   Creates a range vector (like NumPy's arange function).
        /// </summary>
        /// 
        /// <param name="a">The inclusive lower bound of the range.</param>
        /// <param name="b">The exclusive upper bound of the range.</param>
        /// <param name="stepSize">The step size to be taken between elements. 
        ///   This parameter can be negative to create a decreasing range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static double[] Range(double a, double b, ulong stepSize)
        {
            if (a == b)
                return new double[] { };

            if (stepSize == 0)
                throw new ArgumentOutOfRangeException("stepSize", "stepSize must be different from zero.");

            double[] r;

            if (a < b)
            {
                if (stepSize < 0)
                    throw new ArgumentOutOfRangeException("stepSize", "If a < b, stepSize must be positive.");

                uint steps = (uint)System.Math.Ceiling(((double)(b - a) / (double)stepSize));

                r = new double[steps];
                for (uint i = 0; i < r.Length; i++)
                    r[i] = (double)(a +  i * stepSize);
            }
            else
            {
                if (stepSize > 0)
                {
                    uint steps = (uint)System.Math.Ceiling(((double)(a - b) / (double)stepSize));
                    r = new double[steps];
                    for (uint i = 0; i < r.Length; i++)
                        r[i] = (double)(a - i * stepSize);
                }
                else
                {
                    uint steps = (uint)System.Math.Ceiling(((double)(b - a) / (double)stepSize));
                    r = new double[steps];
                    for (uint i = 0; i < r.Length; i++)
                        r[i] = (double)(a + i * stepSize);
                }
            }

            if (a < b)
            {
                if (r[r.Length - 1] > b)
                    r[r.Length - 1] = b;
            }
            else
            {
                if (r[r.Length - 1] > a)
                    r[r.Length - 1] = a;
            }

            return r;
        }

        /// <summary>
        ///   Enumerates through a range (like Python's xrange function).
        /// </summary>
        /// 
        /// <param name="a">The inclusive lower bound of the range.</param>
        /// <param name="b">The exclusive upper bound of the range.</param>
        /// <param name="stepSize">The step size to be taken between elements. 
        ///   This parameter can be negative to create a decreasing range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static IEnumerable<double> EnumerableRange(double a, double b, ulong stepSize)
        {
            if (a == b)
                yield break;

            if (stepSize == 0)
                throw new ArgumentOutOfRangeException("stepSize", "stepSize must be different from zero.");

            double last;

            if (a < b)
            {
                if (stepSize < 0)
                    throw new ArgumentOutOfRangeException("stepSize", "If a < b, stepSize must be positive.");

                uint steps = (uint)System.Math.Ceiling(((double)(b - a) / (double)stepSize)) - 1;
                for (uint i = 0; i < steps; i++)
                    yield return (double)(a +  i * stepSize);
                last = (double)(a +  steps * stepSize);
            }
            else
            {
                if (stepSize > 0)
                {
                    uint steps = (uint)System.Math.Ceiling(((double)(a - b) / (double)stepSize)) - 1;
                    for (uint i = 0; i < steps; i++)
                        yield return (double)(a - i * stepSize);
                    last = (double)(a - steps * stepSize);
                }
                else
                {
                    uint steps = (uint)System.Math.Ceiling(((double)(b - a) / (double)stepSize)) - 1;
                    for (uint i = 0; i < steps; i++)
                        yield return (double)(a + i * stepSize);
                    last = (double)(a + steps * stepSize);
                }
            }

            if (a < b)
            {
                yield return last > b ? b : last;
            }
            else
            {
                yield return last > a ? a : last;
            }
        }

        /// <summary>
        ///   Creates a range vector (like NumPy's arange function).
        /// </summary>
        /// 
        /// <param name="a">The inclusive lower bound of the range.</param>
        /// <param name="b">The exclusive upper bound of the range.</param>
        /// <param name="stepSize">The step size to be taken between elements. 
        ///   This parameter can be negative to create a decreasing range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static double[] Range(double a, double b, ushort stepSize)
        {
            if (a == b)
                return new double[] { };

            if (stepSize == 0)
                throw new ArgumentOutOfRangeException("stepSize", "stepSize must be different from zero.");

            double[] r;

            if (a < b)
            {
                if (stepSize < 0)
                    throw new ArgumentOutOfRangeException("stepSize", "If a < b, stepSize must be positive.");

                uint steps = (uint)System.Math.Ceiling(((double)(b - a) / (double)stepSize));

                r = new double[steps];
                for (uint i = 0; i < r.Length; i++)
                    r[i] = (double)(a +  i * stepSize);
            }
            else
            {
                if (stepSize > 0)
                {
                    uint steps = (uint)System.Math.Ceiling(((double)(a - b) / (double)stepSize));
                    r = new double[steps];
                    for (uint i = 0; i < r.Length; i++)
                        r[i] = (double)(a - i * stepSize);
                }
                else
                {
                    uint steps = (uint)System.Math.Ceiling(((double)(b - a) / (double)stepSize));
                    r = new double[steps];
                    for (uint i = 0; i < r.Length; i++)
                        r[i] = (double)(a + i * stepSize);
                }
            }

            if (a < b)
            {
                if (r[r.Length - 1] > b)
                    r[r.Length - 1] = b;
            }
            else
            {
                if (r[r.Length - 1] > a)
                    r[r.Length - 1] = a;
            }

            return r;
        }

        /// <summary>
        ///   Enumerates through a range (like Python's xrange function).
        /// </summary>
        /// 
        /// <param name="a">The inclusive lower bound of the range.</param>
        /// <param name="b">The exclusive upper bound of the range.</param>
        /// <param name="stepSize">The step size to be taken between elements. 
        ///   This parameter can be negative to create a decreasing range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static IEnumerable<double> EnumerableRange(double a, double b, ushort stepSize)
        {
            if (a == b)
                yield break;

            if (stepSize == 0)
                throw new ArgumentOutOfRangeException("stepSize", "stepSize must be different from zero.");

            double last;

            if (a < b)
            {
                if (stepSize < 0)
                    throw new ArgumentOutOfRangeException("stepSize", "If a < b, stepSize must be positive.");

                uint steps = (uint)System.Math.Ceiling(((double)(b - a) / (double)stepSize)) - 1;
                for (uint i = 0; i < steps; i++)
                    yield return (double)(a +  i * stepSize);
                last = (double)(a +  steps * stepSize);
            }
            else
            {
                if (stepSize > 0)
                {
                    uint steps = (uint)System.Math.Ceiling(((double)(a - b) / (double)stepSize)) - 1;
                    for (uint i = 0; i < steps; i++)
                        yield return (double)(a - i * stepSize);
                    last = (double)(a - steps * stepSize);
                }
                else
                {
                    uint steps = (uint)System.Math.Ceiling(((double)(b - a) / (double)stepSize)) - 1;
                    for (uint i = 0; i < steps; i++)
                        yield return (double)(a + i * stepSize);
                    last = (double)(a + steps * stepSize);
                }
            }

            if (a < b)
            {
                yield return last > b ? b : last;
            }
            else
            {
                yield return last > a ? a : last;
            }
        }

        /// <summary>
        ///   Creates a range vector (like NumPy's arange function).
        /// </summary>
        /// 
        /// <param name="n">The exclusive upper bound of the range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static short[] Range(short n)
        {
            short[] r = new short[(int)n]; 
            for (int i = 0; i < r.Length; i++)
                r[i] = (short)i;
            return r;
        }

        /// <summary>
        ///   Creates a range vector (like NumPy's arange function).
        /// </summary>
        ///
        /// <param name="a">The inclusive lower bound of the range.</param>
        /// <param name="b">The exclusive upper bound of the range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static short[] Range(short a, short b)
        {
            if (a == b)
                return new short[] { };

            short[] r;

            if (b > a)
            {
                r = new short[(int)(b - a)];
                for (int i = 0; i < r.Length; i++)
                    r[i] = (short)(a++);
            }
            else
            {
                r = new short[(int)(a - b)];
                for (int i = 0; i < r.Length; i++)
                    r[i] = (short)(a--);
            }

            return r;
        }

        /// <summary>
        ///   Enumerates through a range (like Python's xrange function).
        /// </summary>
        /// 
        /// <param name="n">The exclusive upper bound of the range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static IEnumerable<short> EnumerableRange(short n)
        {
            for (short i = 0; i < n; i++)
                yield return (short)i;
        }

        /// <summary>
        ///   Enumerates through a range (like Python's xrange).
        /// </summary>
        /// 
        /// <param name="a">The inclusive lower bound of the range.</param>
        /// <param name="b">The exclusive upper bound of the range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static IEnumerable<short> EnumerableRange(short a, short b)
        {
            if (a == b)
                yield break;

            if (b > a)
            {
                int n = (int)(b - a);
                for (int i = 0; i < n; i++)
                    yield return (short)(a++);
            }
            else
            {
                int n = (int)(a - b);
                for (int i = 0; i < n; i++)
                    yield return (short)(a--);
            }
        }


        /// <summary>
        ///   Creates a range vector (like NumPy's arange function).
        /// </summary>
        /// 
        /// <param name="a">The inclusive lower bound of the range.</param>
        /// <param name="b">The exclusive upper bound of the range.</param>
        /// <param name="stepSize">The step size to be taken between elements. 
        ///   This parameter can be negative to create a decreasing range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static float[] Range(short a, short b, float stepSize)
        {
            if (a == b)
                return new float[] { };

            if (stepSize == 0)
                throw new ArgumentOutOfRangeException("stepSize", "stepSize must be different from zero.");

            float[] r;

            if (a < b)
            {
                if (stepSize < 0)
                    throw new ArgumentOutOfRangeException("stepSize", "If a < b, stepSize must be positive.");

                uint steps = (uint)System.Math.Ceiling(((float)(b - a) / (float)stepSize));

                r = new float[steps];
                for (uint i = 0; i < r.Length; i++)
                    r[i] = (float)(a +  i * stepSize);
            }
            else
            {
                if (stepSize > 0)
                {
                    uint steps = (uint)System.Math.Ceiling(((float)(a - b) / (float)stepSize));
                    r = new float[steps];
                    for (uint i = 0; i < r.Length; i++)
                        r[i] = (float)(a - i * stepSize);
                }
                else
                {
                    uint steps = (uint)System.Math.Ceiling(((float)(b - a) / (float)stepSize));
                    r = new float[steps];
                    for (uint i = 0; i < r.Length; i++)
                        r[i] = (float)(a + i * stepSize);
                }
            }

            if (a < b)
            {
                if (r[r.Length - 1] > b)
                    r[r.Length - 1] = b;
            }
            else
            {
                if (r[r.Length - 1] > a)
                    r[r.Length - 1] = a;
            }

            return r;
        }

        /// <summary>
        ///   Enumerates through a range (like Python's xrange function).
        /// </summary>
        /// 
        /// <param name="a">The inclusive lower bound of the range.</param>
        /// <param name="b">The exclusive upper bound of the range.</param>
        /// <param name="stepSize">The step size to be taken between elements. 
        ///   This parameter can be negative to create a decreasing range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static IEnumerable<float> EnumerableRange(short a, short b, float stepSize)
        {
            if (a == b)
                yield break;

            if (stepSize == 0)
                throw new ArgumentOutOfRangeException("stepSize", "stepSize must be different from zero.");

            float last;

            if (a < b)
            {
                if (stepSize < 0)
                    throw new ArgumentOutOfRangeException("stepSize", "If a < b, stepSize must be positive.");

                uint steps = (uint)System.Math.Ceiling(((float)(b - a) / (float)stepSize)) - 1;
                for (uint i = 0; i < steps; i++)
                    yield return (float)(a +  i * stepSize);
                last = (float)(a +  steps * stepSize);
            }
            else
            {
                if (stepSize > 0)
                {
                    uint steps = (uint)System.Math.Ceiling(((float)(a - b) / (float)stepSize)) - 1;
                    for (uint i = 0; i < steps; i++)
                        yield return (float)(a - i * stepSize);
                    last = (float)(a - steps * stepSize);
                }
                else
                {
                    uint steps = (uint)System.Math.Ceiling(((float)(b - a) / (float)stepSize)) - 1;
                    for (uint i = 0; i < steps; i++)
                        yield return (float)(a + i * stepSize);
                    last = (float)(a + steps * stepSize);
                }
            }

            if (a < b)
            {
                yield return last > b ? b : last;
            }
            else
            {
                yield return last > a ? a : last;
            }
        }

        /// <summary>
        ///   Creates a range vector (like NumPy's arange function).
        /// </summary>
        /// 
        /// <param name="a">The inclusive lower bound of the range.</param>
        /// <param name="b">The exclusive upper bound of the range.</param>
        /// <param name="stepSize">The step size to be taken between elements. 
        ///   This parameter can be negative to create a decreasing range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static double[] Range(short a, short b, double stepSize)
        {
            if (a == b)
                return new double[] { };

            if (stepSize == 0)
                throw new ArgumentOutOfRangeException("stepSize", "stepSize must be different from zero.");

            double[] r;

            if (a < b)
            {
                if (stepSize < 0)
                    throw new ArgumentOutOfRangeException("stepSize", "If a < b, stepSize must be positive.");

                uint steps = (uint)System.Math.Ceiling(((double)(b - a) / (double)stepSize));

                r = new double[steps];
                for (uint i = 0; i < r.Length; i++)
                    r[i] = (double)(a +  i * stepSize);
            }
            else
            {
                if (stepSize > 0)
                {
                    uint steps = (uint)System.Math.Ceiling(((double)(a - b) / (double)stepSize));
                    r = new double[steps];
                    for (uint i = 0; i < r.Length; i++)
                        r[i] = (double)(a - i * stepSize);
                }
                else
                {
                    uint steps = (uint)System.Math.Ceiling(((double)(b - a) / (double)stepSize));
                    r = new double[steps];
                    for (uint i = 0; i < r.Length; i++)
                        r[i] = (double)(a + i * stepSize);
                }
            }

            if (a < b)
            {
                if (r[r.Length - 1] > b)
                    r[r.Length - 1] = b;
            }
            else
            {
                if (r[r.Length - 1] > a)
                    r[r.Length - 1] = a;
            }

            return r;
        }

        /// <summary>
        ///   Enumerates through a range (like Python's xrange function).
        /// </summary>
        /// 
        /// <param name="a">The inclusive lower bound of the range.</param>
        /// <param name="b">The exclusive upper bound of the range.</param>
        /// <param name="stepSize">The step size to be taken between elements. 
        ///   This parameter can be negative to create a decreasing range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static IEnumerable<double> EnumerableRange(short a, short b, double stepSize)
        {
            if (a == b)
                yield break;

            if (stepSize == 0)
                throw new ArgumentOutOfRangeException("stepSize", "stepSize must be different from zero.");

            double last;

            if (a < b)
            {
                if (stepSize < 0)
                    throw new ArgumentOutOfRangeException("stepSize", "If a < b, stepSize must be positive.");

                uint steps = (uint)System.Math.Ceiling(((double)(b - a) / (double)stepSize)) - 1;
                for (uint i = 0; i < steps; i++)
                    yield return (double)(a +  i * stepSize);
                last = (double)(a +  steps * stepSize);
            }
            else
            {
                if (stepSize > 0)
                {
                    uint steps = (uint)System.Math.Ceiling(((double)(a - b) / (double)stepSize)) - 1;
                    for (uint i = 0; i < steps; i++)
                        yield return (double)(a - i * stepSize);
                    last = (double)(a - steps * stepSize);
                }
                else
                {
                    uint steps = (uint)System.Math.Ceiling(((double)(b - a) / (double)stepSize)) - 1;
                    for (uint i = 0; i < steps; i++)
                        yield return (double)(a + i * stepSize);
                    last = (double)(a + steps * stepSize);
                }
            }

            if (a < b)
            {
                yield return last > b ? b : last;
            }
            else
            {
                yield return last > a ? a : last;
            }
        }

        /// <summary>
        ///   Creates a range vector (like NumPy's arange function).
        /// </summary>
        /// 
        /// <param name="a">The inclusive lower bound of the range.</param>
        /// <param name="b">The exclusive upper bound of the range.</param>
        /// <param name="stepSize">The step size to be taken between elements. 
        ///   This parameter can be negative to create a decreasing range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static short[] Range(short a, short b, short stepSize)
        {
            if (a == b)
                return new short[] { };

            if (stepSize == 0)
                throw new ArgumentOutOfRangeException("stepSize", "stepSize must be different from zero.");

            short[] r;

            if (a < b)
            {
                if (stepSize < 0)
                    throw new ArgumentOutOfRangeException("stepSize", "If a < b, stepSize must be positive.");

                uint steps = (uint)System.Math.Ceiling(((double)(b - a) / (double)stepSize));

                r = new short[steps];
                for (uint i = 0; i < r.Length; i++)
                    r[i] = (short)(a +  i * stepSize);
            }
            else
            {
                if (stepSize > 0)
                {
                    uint steps = (uint)System.Math.Ceiling(((double)(a - b) / (double)stepSize));
                    r = new short[steps];
                    for (uint i = 0; i < r.Length; i++)
                        r[i] = (short)(a - i * stepSize);
                }
                else
                {
                    uint steps = (uint)System.Math.Ceiling(((double)(b - a) / (double)stepSize));
                    r = new short[steps];
                    for (uint i = 0; i < r.Length; i++)
                        r[i] = (short)(a + i * stepSize);
                }
            }

            if (a < b)
            {
                if (r[r.Length - 1] > b)
                    r[r.Length - 1] = b;
            }
            else
            {
                if (r[r.Length - 1] > a)
                    r[r.Length - 1] = a;
            }

            return r;
        }

        /// <summary>
        ///   Enumerates through a range (like Python's xrange function).
        /// </summary>
        /// 
        /// <param name="a">The inclusive lower bound of the range.</param>
        /// <param name="b">The exclusive upper bound of the range.</param>
        /// <param name="stepSize">The step size to be taken between elements. 
        ///   This parameter can be negative to create a decreasing range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static IEnumerable<short> EnumerableRange(short a, short b, short stepSize)
        {
            if (a == b)
                yield break;

            if (stepSize == 0)
                throw new ArgumentOutOfRangeException("stepSize", "stepSize must be different from zero.");

            short last;

            if (a < b)
            {
                if (stepSize < 0)
                    throw new ArgumentOutOfRangeException("stepSize", "If a < b, stepSize must be positive.");

                uint steps = (uint)System.Math.Ceiling(((double)(b - a) / (double)stepSize)) - 1;
                for (uint i = 0; i < steps; i++)
                    yield return (short)(a +  i * stepSize);
                last = (short)(a +  steps * stepSize);
            }
            else
            {
                if (stepSize > 0)
                {
                    uint steps = (uint)System.Math.Ceiling(((double)(a - b) / (double)stepSize)) - 1;
                    for (uint i = 0; i < steps; i++)
                        yield return (short)(a - i * stepSize);
                    last = (short)(a - steps * stepSize);
                }
                else
                {
                    uint steps = (uint)System.Math.Ceiling(((double)(b - a) / (double)stepSize)) - 1;
                    for (uint i = 0; i < steps; i++)
                        yield return (short)(a + i * stepSize);
                    last = (short)(a + steps * stepSize);
                }
            }

            if (a < b)
            {
                yield return last > b ? b : last;
            }
            else
            {
                yield return last > a ? a : last;
            }
        }

        /// <summary>
        ///   Creates a range vector (like NumPy's arange function).
        /// </summary>
        /// 
        /// <param name="n">The exclusive upper bound of the range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static byte[] Range(byte n)
        {
            byte[] r = new byte[(int)n]; 
            for (int i = 0; i < r.Length; i++)
                r[i] = (byte)i;
            return r;
        }

        /// <summary>
        ///   Creates a range vector (like NumPy's arange function).
        /// </summary>
        ///
        /// <param name="a">The inclusive lower bound of the range.</param>
        /// <param name="b">The exclusive upper bound of the range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static byte[] Range(byte a, byte b)
        {
            if (a == b)
                return new byte[] { };

            byte[] r;

            if (b > a)
            {
                r = new byte[(int)(b - a)];
                for (int i = 0; i < r.Length; i++)
                    r[i] = (byte)(a++);
            }
            else
            {
                r = new byte[(int)(a - b)];
                for (int i = 0; i < r.Length; i++)
                    r[i] = (byte)(a--);
            }

            return r;
        }

        /// <summary>
        ///   Enumerates through a range (like Python's xrange function).
        /// </summary>
        /// 
        /// <param name="n">The exclusive upper bound of the range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static IEnumerable<byte> EnumerableRange(byte n)
        {
            for (byte i = 0; i < n; i++)
                yield return (byte)i;
        }

        /// <summary>
        ///   Enumerates through a range (like Python's xrange).
        /// </summary>
        /// 
        /// <param name="a">The inclusive lower bound of the range.</param>
        /// <param name="b">The exclusive upper bound of the range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static IEnumerable<byte> EnumerableRange(byte a, byte b)
        {
            if (a == b)
                yield break;

            if (b > a)
            {
                int n = (int)(b - a);
                for (int i = 0; i < n; i++)
                    yield return (byte)(a++);
            }
            else
            {
                int n = (int)(a - b);
                for (int i = 0; i < n; i++)
                    yield return (byte)(a--);
            }
        }


        /// <summary>
        ///   Creates a range vector (like NumPy's arange function).
        /// </summary>
        /// 
        /// <param name="a">The inclusive lower bound of the range.</param>
        /// <param name="b">The exclusive upper bound of the range.</param>
        /// <param name="stepSize">The step size to be taken between elements. 
        ///   This parameter can be negative to create a decreasing range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static float[] Range(byte a, byte b, float stepSize)
        {
            if (a == b)
                return new float[] { };

            if (stepSize == 0)
                throw new ArgumentOutOfRangeException("stepSize", "stepSize must be different from zero.");

            float[] r;

            if (a < b)
            {
                if (stepSize < 0)
                    throw new ArgumentOutOfRangeException("stepSize", "If a < b, stepSize must be positive.");

                uint steps = (uint)System.Math.Ceiling(((float)(b - a) / (float)stepSize));

                r = new float[steps];
                for (uint i = 0; i < r.Length; i++)
                    r[i] = (float)(a +  i * stepSize);
            }
            else
            {
                if (stepSize > 0)
                {
                    uint steps = (uint)System.Math.Ceiling(((float)(a - b) / (float)stepSize));
                    r = new float[steps];
                    for (uint i = 0; i < r.Length; i++)
                        r[i] = (float)(a - i * stepSize);
                }
                else
                {
                    uint steps = (uint)System.Math.Ceiling(((float)(b - a) / (float)stepSize));
                    r = new float[steps];
                    for (uint i = 0; i < r.Length; i++)
                        r[i] = (float)(a + i * stepSize);
                }
            }

            if (a < b)
            {
                if (r[r.Length - 1] > b)
                    r[r.Length - 1] = b;
            }
            else
            {
                if (r[r.Length - 1] > a)
                    r[r.Length - 1] = a;
            }

            return r;
        }

        /// <summary>
        ///   Enumerates through a range (like Python's xrange function).
        /// </summary>
        /// 
        /// <param name="a">The inclusive lower bound of the range.</param>
        /// <param name="b">The exclusive upper bound of the range.</param>
        /// <param name="stepSize">The step size to be taken between elements. 
        ///   This parameter can be negative to create a decreasing range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static IEnumerable<float> EnumerableRange(byte a, byte b, float stepSize)
        {
            if (a == b)
                yield break;

            if (stepSize == 0)
                throw new ArgumentOutOfRangeException("stepSize", "stepSize must be different from zero.");

            float last;

            if (a < b)
            {
                if (stepSize < 0)
                    throw new ArgumentOutOfRangeException("stepSize", "If a < b, stepSize must be positive.");

                uint steps = (uint)System.Math.Ceiling(((float)(b - a) / (float)stepSize)) - 1;
                for (uint i = 0; i < steps; i++)
                    yield return (float)(a +  i * stepSize);
                last = (float)(a +  steps * stepSize);
            }
            else
            {
                if (stepSize > 0)
                {
                    uint steps = (uint)System.Math.Ceiling(((float)(a - b) / (float)stepSize)) - 1;
                    for (uint i = 0; i < steps; i++)
                        yield return (float)(a - i * stepSize);
                    last = (float)(a - steps * stepSize);
                }
                else
                {
                    uint steps = (uint)System.Math.Ceiling(((float)(b - a) / (float)stepSize)) - 1;
                    for (uint i = 0; i < steps; i++)
                        yield return (float)(a + i * stepSize);
                    last = (float)(a + steps * stepSize);
                }
            }

            if (a < b)
            {
                yield return last > b ? b : last;
            }
            else
            {
                yield return last > a ? a : last;
            }
        }

        /// <summary>
        ///   Creates a range vector (like NumPy's arange function).
        /// </summary>
        /// 
        /// <param name="a">The inclusive lower bound of the range.</param>
        /// <param name="b">The exclusive upper bound of the range.</param>
        /// <param name="stepSize">The step size to be taken between elements. 
        ///   This parameter can be negative to create a decreasing range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static double[] Range(byte a, byte b, double stepSize)
        {
            if (a == b)
                return new double[] { };

            if (stepSize == 0)
                throw new ArgumentOutOfRangeException("stepSize", "stepSize must be different from zero.");

            double[] r;

            if (a < b)
            {
                if (stepSize < 0)
                    throw new ArgumentOutOfRangeException("stepSize", "If a < b, stepSize must be positive.");

                uint steps = (uint)System.Math.Ceiling(((double)(b - a) / (double)stepSize));

                r = new double[steps];
                for (uint i = 0; i < r.Length; i++)
                    r[i] = (double)(a +  i * stepSize);
            }
            else
            {
                if (stepSize > 0)
                {
                    uint steps = (uint)System.Math.Ceiling(((double)(a - b) / (double)stepSize));
                    r = new double[steps];
                    for (uint i = 0; i < r.Length; i++)
                        r[i] = (double)(a - i * stepSize);
                }
                else
                {
                    uint steps = (uint)System.Math.Ceiling(((double)(b - a) / (double)stepSize));
                    r = new double[steps];
                    for (uint i = 0; i < r.Length; i++)
                        r[i] = (double)(a + i * stepSize);
                }
            }

            if (a < b)
            {
                if (r[r.Length - 1] > b)
                    r[r.Length - 1] = b;
            }
            else
            {
                if (r[r.Length - 1] > a)
                    r[r.Length - 1] = a;
            }

            return r;
        }

        /// <summary>
        ///   Enumerates through a range (like Python's xrange function).
        /// </summary>
        /// 
        /// <param name="a">The inclusive lower bound of the range.</param>
        /// <param name="b">The exclusive upper bound of the range.</param>
        /// <param name="stepSize">The step size to be taken between elements. 
        ///   This parameter can be negative to create a decreasing range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static IEnumerable<double> EnumerableRange(byte a, byte b, double stepSize)
        {
            if (a == b)
                yield break;

            if (stepSize == 0)
                throw new ArgumentOutOfRangeException("stepSize", "stepSize must be different from zero.");

            double last;

            if (a < b)
            {
                if (stepSize < 0)
                    throw new ArgumentOutOfRangeException("stepSize", "If a < b, stepSize must be positive.");

                uint steps = (uint)System.Math.Ceiling(((double)(b - a) / (double)stepSize)) - 1;
                for (uint i = 0; i < steps; i++)
                    yield return (double)(a +  i * stepSize);
                last = (double)(a +  steps * stepSize);
            }
            else
            {
                if (stepSize > 0)
                {
                    uint steps = (uint)System.Math.Ceiling(((double)(a - b) / (double)stepSize)) - 1;
                    for (uint i = 0; i < steps; i++)
                        yield return (double)(a - i * stepSize);
                    last = (double)(a - steps * stepSize);
                }
                else
                {
                    uint steps = (uint)System.Math.Ceiling(((double)(b - a) / (double)stepSize)) - 1;
                    for (uint i = 0; i < steps; i++)
                        yield return (double)(a + i * stepSize);
                    last = (double)(a + steps * stepSize);
                }
            }

            if (a < b)
            {
                yield return last > b ? b : last;
            }
            else
            {
                yield return last > a ? a : last;
            }
        }

        /// <summary>
        ///   Creates a range vector (like NumPy's arange function).
        /// </summary>
        /// 
        /// <param name="a">The inclusive lower bound of the range.</param>
        /// <param name="b">The exclusive upper bound of the range.</param>
        /// <param name="stepSize">The step size to be taken between elements. 
        ///   This parameter can be negative to create a decreasing range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static byte[] Range(byte a, byte b, byte stepSize)
        {
            if (a == b)
                return new byte[] { };

            if (stepSize == 0)
                throw new ArgumentOutOfRangeException("stepSize", "stepSize must be different from zero.");

            byte[] r;

            if (a < b)
            {
                if (stepSize < 0)
                    throw new ArgumentOutOfRangeException("stepSize", "If a < b, stepSize must be positive.");

                uint steps = (uint)System.Math.Ceiling(((double)(b - a) / (double)stepSize));

                r = new byte[steps];
                for (uint i = 0; i < r.Length; i++)
                    r[i] = (byte)(a +  i * stepSize);
            }
            else
            {
                if (stepSize > 0)
                {
                    uint steps = (uint)System.Math.Ceiling(((double)(a - b) / (double)stepSize));
                    r = new byte[steps];
                    for (uint i = 0; i < r.Length; i++)
                        r[i] = (byte)(a - i * stepSize);
                }
                else
                {
                    uint steps = (uint)System.Math.Ceiling(((double)(b - a) / (double)stepSize));
                    r = new byte[steps];
                    for (uint i = 0; i < r.Length; i++)
                        r[i] = (byte)(a + i * stepSize);
                }
            }

            if (a < b)
            {
                if (r[r.Length - 1] > b)
                    r[r.Length - 1] = b;
            }
            else
            {
                if (r[r.Length - 1] > a)
                    r[r.Length - 1] = a;
            }

            return r;
        }

        /// <summary>
        ///   Enumerates through a range (like Python's xrange function).
        /// </summary>
        /// 
        /// <param name="a">The inclusive lower bound of the range.</param>
        /// <param name="b">The exclusive upper bound of the range.</param>
        /// <param name="stepSize">The step size to be taken between elements. 
        ///   This parameter can be negative to create a decreasing range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static IEnumerable<byte> EnumerableRange(byte a, byte b, byte stepSize)
        {
            if (a == b)
                yield break;

            if (stepSize == 0)
                throw new ArgumentOutOfRangeException("stepSize", "stepSize must be different from zero.");

            byte last;

            if (a < b)
            {
                if (stepSize < 0)
                    throw new ArgumentOutOfRangeException("stepSize", "If a < b, stepSize must be positive.");

                uint steps = (uint)System.Math.Ceiling(((double)(b - a) / (double)stepSize)) - 1;
                for (uint i = 0; i < steps; i++)
                    yield return (byte)(a +  i * stepSize);
                last = (byte)(a +  steps * stepSize);
            }
            else
            {
                if (stepSize > 0)
                {
                    uint steps = (uint)System.Math.Ceiling(((double)(a - b) / (double)stepSize)) - 1;
                    for (uint i = 0; i < steps; i++)
                        yield return (byte)(a - i * stepSize);
                    last = (byte)(a - steps * stepSize);
                }
                else
                {
                    uint steps = (uint)System.Math.Ceiling(((double)(b - a) / (double)stepSize)) - 1;
                    for (uint i = 0; i < steps; i++)
                        yield return (byte)(a + i * stepSize);
                    last = (byte)(a + steps * stepSize);
                }
            }

            if (a < b)
            {
                yield return last > b ? b : last;
            }
            else
            {
                yield return last > a ? a : last;
            }
        }

        /// <summary>
        ///   Creates a range vector (like NumPy's arange function).
        /// </summary>
        /// 
        /// <param name="n">The exclusive upper bound of the range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static sbyte[] Range(sbyte n)
        {
            sbyte[] r = new sbyte[(int)n]; 
            for (int i = 0; i < r.Length; i++)
                r[i] = (sbyte)i;
            return r;
        }

        /// <summary>
        ///   Creates a range vector (like NumPy's arange function).
        /// </summary>
        ///
        /// <param name="a">The inclusive lower bound of the range.</param>
        /// <param name="b">The exclusive upper bound of the range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static sbyte[] Range(sbyte a, sbyte b)
        {
            if (a == b)
                return new sbyte[] { };

            sbyte[] r;

            if (b > a)
            {
                r = new sbyte[(int)(b - a)];
                for (int i = 0; i < r.Length; i++)
                    r[i] = (sbyte)(a++);
            }
            else
            {
                r = new sbyte[(int)(a - b)];
                for (int i = 0; i < r.Length; i++)
                    r[i] = (sbyte)(a--);
            }

            return r;
        }

        /// <summary>
        ///   Enumerates through a range (like Python's xrange function).
        /// </summary>
        /// 
        /// <param name="n">The exclusive upper bound of the range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static IEnumerable<sbyte> EnumerableRange(sbyte n)
        {
            for (sbyte i = 0; i < n; i++)
                yield return (sbyte)i;
        }

        /// <summary>
        ///   Enumerates through a range (like Python's xrange).
        /// </summary>
        /// 
        /// <param name="a">The inclusive lower bound of the range.</param>
        /// <param name="b">The exclusive upper bound of the range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static IEnumerable<sbyte> EnumerableRange(sbyte a, sbyte b)
        {
            if (a == b)
                yield break;

            if (b > a)
            {
                int n = (int)(b - a);
                for (int i = 0; i < n; i++)
                    yield return (sbyte)(a++);
            }
            else
            {
                int n = (int)(a - b);
                for (int i = 0; i < n; i++)
                    yield return (sbyte)(a--);
            }
        }


        /// <summary>
        ///   Creates a range vector (like NumPy's arange function).
        /// </summary>
        /// 
        /// <param name="a">The inclusive lower bound of the range.</param>
        /// <param name="b">The exclusive upper bound of the range.</param>
        /// <param name="stepSize">The step size to be taken between elements. 
        ///   This parameter can be negative to create a decreasing range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static float[] Range(sbyte a, sbyte b, float stepSize)
        {
            if (a == b)
                return new float[] { };

            if (stepSize == 0)
                throw new ArgumentOutOfRangeException("stepSize", "stepSize must be different from zero.");

            float[] r;

            if (a < b)
            {
                if (stepSize < 0)
                    throw new ArgumentOutOfRangeException("stepSize", "If a < b, stepSize must be positive.");

                uint steps = (uint)System.Math.Ceiling(((float)(b - a) / (float)stepSize));

                r = new float[steps];
                for (uint i = 0; i < r.Length; i++)
                    r[i] = (float)(a +  i * stepSize);
            }
            else
            {
                if (stepSize > 0)
                {
                    uint steps = (uint)System.Math.Ceiling(((float)(a - b) / (float)stepSize));
                    r = new float[steps];
                    for (uint i = 0; i < r.Length; i++)
                        r[i] = (float)(a - i * stepSize);
                }
                else
                {
                    uint steps = (uint)System.Math.Ceiling(((float)(b - a) / (float)stepSize));
                    r = new float[steps];
                    for (uint i = 0; i < r.Length; i++)
                        r[i] = (float)(a + i * stepSize);
                }
            }

            if (a < b)
            {
                if (r[r.Length - 1] > b)
                    r[r.Length - 1] = b;
            }
            else
            {
                if (r[r.Length - 1] > a)
                    r[r.Length - 1] = a;
            }

            return r;
        }

        /// <summary>
        ///   Enumerates through a range (like Python's xrange function).
        /// </summary>
        /// 
        /// <param name="a">The inclusive lower bound of the range.</param>
        /// <param name="b">The exclusive upper bound of the range.</param>
        /// <param name="stepSize">The step size to be taken between elements. 
        ///   This parameter can be negative to create a decreasing range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static IEnumerable<float> EnumerableRange(sbyte a, sbyte b, float stepSize)
        {
            if (a == b)
                yield break;

            if (stepSize == 0)
                throw new ArgumentOutOfRangeException("stepSize", "stepSize must be different from zero.");

            float last;

            if (a < b)
            {
                if (stepSize < 0)
                    throw new ArgumentOutOfRangeException("stepSize", "If a < b, stepSize must be positive.");

                uint steps = (uint)System.Math.Ceiling(((float)(b - a) / (float)stepSize)) - 1;
                for (uint i = 0; i < steps; i++)
                    yield return (float)(a +  i * stepSize);
                last = (float)(a +  steps * stepSize);
            }
            else
            {
                if (stepSize > 0)
                {
                    uint steps = (uint)System.Math.Ceiling(((float)(a - b) / (float)stepSize)) - 1;
                    for (uint i = 0; i < steps; i++)
                        yield return (float)(a - i * stepSize);
                    last = (float)(a - steps * stepSize);
                }
                else
                {
                    uint steps = (uint)System.Math.Ceiling(((float)(b - a) / (float)stepSize)) - 1;
                    for (uint i = 0; i < steps; i++)
                        yield return (float)(a + i * stepSize);
                    last = (float)(a + steps * stepSize);
                }
            }

            if (a < b)
            {
                yield return last > b ? b : last;
            }
            else
            {
                yield return last > a ? a : last;
            }
        }

        /// <summary>
        ///   Creates a range vector (like NumPy's arange function).
        /// </summary>
        /// 
        /// <param name="a">The inclusive lower bound of the range.</param>
        /// <param name="b">The exclusive upper bound of the range.</param>
        /// <param name="stepSize">The step size to be taken between elements. 
        ///   This parameter can be negative to create a decreasing range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static double[] Range(sbyte a, sbyte b, double stepSize)
        {
            if (a == b)
                return new double[] { };

            if (stepSize == 0)
                throw new ArgumentOutOfRangeException("stepSize", "stepSize must be different from zero.");

            double[] r;

            if (a < b)
            {
                if (stepSize < 0)
                    throw new ArgumentOutOfRangeException("stepSize", "If a < b, stepSize must be positive.");

                uint steps = (uint)System.Math.Ceiling(((double)(b - a) / (double)stepSize));

                r = new double[steps];
                for (uint i = 0; i < r.Length; i++)
                    r[i] = (double)(a +  i * stepSize);
            }
            else
            {
                if (stepSize > 0)
                {
                    uint steps = (uint)System.Math.Ceiling(((double)(a - b) / (double)stepSize));
                    r = new double[steps];
                    for (uint i = 0; i < r.Length; i++)
                        r[i] = (double)(a - i * stepSize);
                }
                else
                {
                    uint steps = (uint)System.Math.Ceiling(((double)(b - a) / (double)stepSize));
                    r = new double[steps];
                    for (uint i = 0; i < r.Length; i++)
                        r[i] = (double)(a + i * stepSize);
                }
            }

            if (a < b)
            {
                if (r[r.Length - 1] > b)
                    r[r.Length - 1] = b;
            }
            else
            {
                if (r[r.Length - 1] > a)
                    r[r.Length - 1] = a;
            }

            return r;
        }

        /// <summary>
        ///   Enumerates through a range (like Python's xrange function).
        /// </summary>
        /// 
        /// <param name="a">The inclusive lower bound of the range.</param>
        /// <param name="b">The exclusive upper bound of the range.</param>
        /// <param name="stepSize">The step size to be taken between elements. 
        ///   This parameter can be negative to create a decreasing range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static IEnumerable<double> EnumerableRange(sbyte a, sbyte b, double stepSize)
        {
            if (a == b)
                yield break;

            if (stepSize == 0)
                throw new ArgumentOutOfRangeException("stepSize", "stepSize must be different from zero.");

            double last;

            if (a < b)
            {
                if (stepSize < 0)
                    throw new ArgumentOutOfRangeException("stepSize", "If a < b, stepSize must be positive.");

                uint steps = (uint)System.Math.Ceiling(((double)(b - a) / (double)stepSize)) - 1;
                for (uint i = 0; i < steps; i++)
                    yield return (double)(a +  i * stepSize);
                last = (double)(a +  steps * stepSize);
            }
            else
            {
                if (stepSize > 0)
                {
                    uint steps = (uint)System.Math.Ceiling(((double)(a - b) / (double)stepSize)) - 1;
                    for (uint i = 0; i < steps; i++)
                        yield return (double)(a - i * stepSize);
                    last = (double)(a - steps * stepSize);
                }
                else
                {
                    uint steps = (uint)System.Math.Ceiling(((double)(b - a) / (double)stepSize)) - 1;
                    for (uint i = 0; i < steps; i++)
                        yield return (double)(a + i * stepSize);
                    last = (double)(a + steps * stepSize);
                }
            }

            if (a < b)
            {
                yield return last > b ? b : last;
            }
            else
            {
                yield return last > a ? a : last;
            }
        }

        /// <summary>
        ///   Creates a range vector (like NumPy's arange function).
        /// </summary>
        /// 
        /// <param name="a">The inclusive lower bound of the range.</param>
        /// <param name="b">The exclusive upper bound of the range.</param>
        /// <param name="stepSize">The step size to be taken between elements. 
        ///   This parameter can be negative to create a decreasing range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static sbyte[] Range(sbyte a, sbyte b, sbyte stepSize)
        {
            if (a == b)
                return new sbyte[] { };

            if (stepSize == 0)
                throw new ArgumentOutOfRangeException("stepSize", "stepSize must be different from zero.");

            sbyte[] r;

            if (a < b)
            {
                if (stepSize < 0)
                    throw new ArgumentOutOfRangeException("stepSize", "If a < b, stepSize must be positive.");

                uint steps = (uint)System.Math.Ceiling(((double)(b - a) / (double)stepSize));

                r = new sbyte[steps];
                for (uint i = 0; i < r.Length; i++)
                    r[i] = (sbyte)(a +  i * stepSize);
            }
            else
            {
                if (stepSize > 0)
                {
                    uint steps = (uint)System.Math.Ceiling(((double)(a - b) / (double)stepSize));
                    r = new sbyte[steps];
                    for (uint i = 0; i < r.Length; i++)
                        r[i] = (sbyte)(a - i * stepSize);
                }
                else
                {
                    uint steps = (uint)System.Math.Ceiling(((double)(b - a) / (double)stepSize));
                    r = new sbyte[steps];
                    for (uint i = 0; i < r.Length; i++)
                        r[i] = (sbyte)(a + i * stepSize);
                }
            }

            if (a < b)
            {
                if (r[r.Length - 1] > b)
                    r[r.Length - 1] = b;
            }
            else
            {
                if (r[r.Length - 1] > a)
                    r[r.Length - 1] = a;
            }

            return r;
        }

        /// <summary>
        ///   Enumerates through a range (like Python's xrange function).
        /// </summary>
        /// 
        /// <param name="a">The inclusive lower bound of the range.</param>
        /// <param name="b">The exclusive upper bound of the range.</param>
        /// <param name="stepSize">The step size to be taken between elements. 
        ///   This parameter can be negative to create a decreasing range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static IEnumerable<sbyte> EnumerableRange(sbyte a, sbyte b, sbyte stepSize)
        {
            if (a == b)
                yield break;

            if (stepSize == 0)
                throw new ArgumentOutOfRangeException("stepSize", "stepSize must be different from zero.");

            sbyte last;

            if (a < b)
            {
                if (stepSize < 0)
                    throw new ArgumentOutOfRangeException("stepSize", "If a < b, stepSize must be positive.");

                uint steps = (uint)System.Math.Ceiling(((double)(b - a) / (double)stepSize)) - 1;
                for (uint i = 0; i < steps; i++)
                    yield return (sbyte)(a +  i * stepSize);
                last = (sbyte)(a +  steps * stepSize);
            }
            else
            {
                if (stepSize > 0)
                {
                    uint steps = (uint)System.Math.Ceiling(((double)(a - b) / (double)stepSize)) - 1;
                    for (uint i = 0; i < steps; i++)
                        yield return (sbyte)(a - i * stepSize);
                    last = (sbyte)(a - steps * stepSize);
                }
                else
                {
                    uint steps = (uint)System.Math.Ceiling(((double)(b - a) / (double)stepSize)) - 1;
                    for (uint i = 0; i < steps; i++)
                        yield return (sbyte)(a + i * stepSize);
                    last = (sbyte)(a + steps * stepSize);
                }
            }

            if (a < b)
            {
                yield return last > b ? b : last;
            }
            else
            {
                yield return last > a ? a : last;
            }
        }

        /// <summary>
        ///   Creates a range vector (like NumPy's arange function).
        /// </summary>
        /// 
        /// <param name="n">The exclusive upper bound of the range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static long[] Range(long n)
        {
            long[] r = new long[(int)n]; 
            for (int i = 0; i < r.Length; i++)
                r[i] = (long)i;
            return r;
        }

        /// <summary>
        ///   Creates a range vector (like NumPy's arange function).
        /// </summary>
        ///
        /// <param name="a">The inclusive lower bound of the range.</param>
        /// <param name="b">The exclusive upper bound of the range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static long[] Range(long a, long b)
        {
            if (a == b)
                return new long[] { };

            long[] r;

            if (b > a)
            {
                r = new long[(int)(b - a)];
                for (int i = 0; i < r.Length; i++)
                    r[i] = (long)(a++);
            }
            else
            {
                r = new long[(int)(a - b)];
                for (int i = 0; i < r.Length; i++)
                    r[i] = (long)(a--);
            }

            return r;
        }

        /// <summary>
        ///   Enumerates through a range (like Python's xrange function).
        /// </summary>
        /// 
        /// <param name="n">The exclusive upper bound of the range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static IEnumerable<long> EnumerableRange(long n)
        {
            for (long i = 0; i < n; i++)
                yield return (long)i;
        }

        /// <summary>
        ///   Enumerates through a range (like Python's xrange).
        /// </summary>
        /// 
        /// <param name="a">The inclusive lower bound of the range.</param>
        /// <param name="b">The exclusive upper bound of the range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static IEnumerable<long> EnumerableRange(long a, long b)
        {
            if (a == b)
                yield break;

            if (b > a)
            {
                int n = (int)(b - a);
                for (int i = 0; i < n; i++)
                    yield return (long)(a++);
            }
            else
            {
                int n = (int)(a - b);
                for (int i = 0; i < n; i++)
                    yield return (long)(a--);
            }
        }


        /// <summary>
        ///   Creates a range vector (like NumPy's arange function).
        /// </summary>
        /// 
        /// <param name="a">The inclusive lower bound of the range.</param>
        /// <param name="b">The exclusive upper bound of the range.</param>
        /// <param name="stepSize">The step size to be taken between elements. 
        ///   This parameter can be negative to create a decreasing range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static float[] Range(long a, long b, float stepSize)
        {
            if (a == b)
                return new float[] { };

            if (stepSize == 0)
                throw new ArgumentOutOfRangeException("stepSize", "stepSize must be different from zero.");

            float[] r;

            if (a < b)
            {
                if (stepSize < 0)
                    throw new ArgumentOutOfRangeException("stepSize", "If a < b, stepSize must be positive.");

                uint steps = (uint)System.Math.Ceiling(((float)(b - a) / (float)stepSize));

                r = new float[steps];
                for (uint i = 0; i < r.Length; i++)
                    r[i] = (float)(a +  i * stepSize);
            }
            else
            {
                if (stepSize > 0)
                {
                    uint steps = (uint)System.Math.Ceiling(((float)(a - b) / (float)stepSize));
                    r = new float[steps];
                    for (uint i = 0; i < r.Length; i++)
                        r[i] = (float)(a - i * stepSize);
                }
                else
                {
                    uint steps = (uint)System.Math.Ceiling(((float)(b - a) / (float)stepSize));
                    r = new float[steps];
                    for (uint i = 0; i < r.Length; i++)
                        r[i] = (float)(a + i * stepSize);
                }
            }

            if (a < b)
            {
                if (r[r.Length - 1] > b)
                    r[r.Length - 1] = b;
            }
            else
            {
                if (r[r.Length - 1] > a)
                    r[r.Length - 1] = a;
            }

            return r;
        }

        /// <summary>
        ///   Enumerates through a range (like Python's xrange function).
        /// </summary>
        /// 
        /// <param name="a">The inclusive lower bound of the range.</param>
        /// <param name="b">The exclusive upper bound of the range.</param>
        /// <param name="stepSize">The step size to be taken between elements. 
        ///   This parameter can be negative to create a decreasing range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static IEnumerable<float> EnumerableRange(long a, long b, float stepSize)
        {
            if (a == b)
                yield break;

            if (stepSize == 0)
                throw new ArgumentOutOfRangeException("stepSize", "stepSize must be different from zero.");

            float last;

            if (a < b)
            {
                if (stepSize < 0)
                    throw new ArgumentOutOfRangeException("stepSize", "If a < b, stepSize must be positive.");

                uint steps = (uint)System.Math.Ceiling(((float)(b - a) / (float)stepSize)) - 1;
                for (uint i = 0; i < steps; i++)
                    yield return (float)(a +  i * stepSize);
                last = (float)(a +  steps * stepSize);
            }
            else
            {
                if (stepSize > 0)
                {
                    uint steps = (uint)System.Math.Ceiling(((float)(a - b) / (float)stepSize)) - 1;
                    for (uint i = 0; i < steps; i++)
                        yield return (float)(a - i * stepSize);
                    last = (float)(a - steps * stepSize);
                }
                else
                {
                    uint steps = (uint)System.Math.Ceiling(((float)(b - a) / (float)stepSize)) - 1;
                    for (uint i = 0; i < steps; i++)
                        yield return (float)(a + i * stepSize);
                    last = (float)(a + steps * stepSize);
                }
            }

            if (a < b)
            {
                yield return last > b ? b : last;
            }
            else
            {
                yield return last > a ? a : last;
            }
        }

        /// <summary>
        ///   Creates a range vector (like NumPy's arange function).
        /// </summary>
        /// 
        /// <param name="a">The inclusive lower bound of the range.</param>
        /// <param name="b">The exclusive upper bound of the range.</param>
        /// <param name="stepSize">The step size to be taken between elements. 
        ///   This parameter can be negative to create a decreasing range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static double[] Range(long a, long b, double stepSize)
        {
            if (a == b)
                return new double[] { };

            if (stepSize == 0)
                throw new ArgumentOutOfRangeException("stepSize", "stepSize must be different from zero.");

            double[] r;

            if (a < b)
            {
                if (stepSize < 0)
                    throw new ArgumentOutOfRangeException("stepSize", "If a < b, stepSize must be positive.");

                uint steps = (uint)System.Math.Ceiling(((double)(b - a) / (double)stepSize));

                r = new double[steps];
                for (uint i = 0; i < r.Length; i++)
                    r[i] = (double)(a +  i * stepSize);
            }
            else
            {
                if (stepSize > 0)
                {
                    uint steps = (uint)System.Math.Ceiling(((double)(a - b) / (double)stepSize));
                    r = new double[steps];
                    for (uint i = 0; i < r.Length; i++)
                        r[i] = (double)(a - i * stepSize);
                }
                else
                {
                    uint steps = (uint)System.Math.Ceiling(((double)(b - a) / (double)stepSize));
                    r = new double[steps];
                    for (uint i = 0; i < r.Length; i++)
                        r[i] = (double)(a + i * stepSize);
                }
            }

            if (a < b)
            {
                if (r[r.Length - 1] > b)
                    r[r.Length - 1] = b;
            }
            else
            {
                if (r[r.Length - 1] > a)
                    r[r.Length - 1] = a;
            }

            return r;
        }

        /// <summary>
        ///   Enumerates through a range (like Python's xrange function).
        /// </summary>
        /// 
        /// <param name="a">The inclusive lower bound of the range.</param>
        /// <param name="b">The exclusive upper bound of the range.</param>
        /// <param name="stepSize">The step size to be taken between elements. 
        ///   This parameter can be negative to create a decreasing range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static IEnumerable<double> EnumerableRange(long a, long b, double stepSize)
        {
            if (a == b)
                yield break;

            if (stepSize == 0)
                throw new ArgumentOutOfRangeException("stepSize", "stepSize must be different from zero.");

            double last;

            if (a < b)
            {
                if (stepSize < 0)
                    throw new ArgumentOutOfRangeException("stepSize", "If a < b, stepSize must be positive.");

                uint steps = (uint)System.Math.Ceiling(((double)(b - a) / (double)stepSize)) - 1;
                for (uint i = 0; i < steps; i++)
                    yield return (double)(a +  i * stepSize);
                last = (double)(a +  steps * stepSize);
            }
            else
            {
                if (stepSize > 0)
                {
                    uint steps = (uint)System.Math.Ceiling(((double)(a - b) / (double)stepSize)) - 1;
                    for (uint i = 0; i < steps; i++)
                        yield return (double)(a - i * stepSize);
                    last = (double)(a - steps * stepSize);
                }
                else
                {
                    uint steps = (uint)System.Math.Ceiling(((double)(b - a) / (double)stepSize)) - 1;
                    for (uint i = 0; i < steps; i++)
                        yield return (double)(a + i * stepSize);
                    last = (double)(a + steps * stepSize);
                }
            }

            if (a < b)
            {
                yield return last > b ? b : last;
            }
            else
            {
                yield return last > a ? a : last;
            }
        }

        /// <summary>
        ///   Creates a range vector (like NumPy's arange function).
        /// </summary>
        /// 
        /// <param name="a">The inclusive lower bound of the range.</param>
        /// <param name="b">The exclusive upper bound of the range.</param>
        /// <param name="stepSize">The step size to be taken between elements. 
        ///   This parameter can be negative to create a decreasing range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static long[] Range(long a, long b, long stepSize)
        {
            if (a == b)
                return new long[] { };

            if (stepSize == 0)
                throw new ArgumentOutOfRangeException("stepSize", "stepSize must be different from zero.");

            long[] r;

            if (a < b)
            {
                if (stepSize < 0)
                    throw new ArgumentOutOfRangeException("stepSize", "If a < b, stepSize must be positive.");

                uint steps = (uint)System.Math.Ceiling(((double)(b - a) / (double)stepSize));

                r = new long[steps];
                for (uint i = 0; i < r.Length; i++)
                    r[i] = (long)(a +  i * stepSize);
            }
            else
            {
                if (stepSize > 0)
                {
                    uint steps = (uint)System.Math.Ceiling(((double)(a - b) / (double)stepSize));
                    r = new long[steps];
                    for (uint i = 0; i < r.Length; i++)
                        r[i] = (long)(a - i * stepSize);
                }
                else
                {
                    uint steps = (uint)System.Math.Ceiling(((double)(b - a) / (double)stepSize));
                    r = new long[steps];
                    for (uint i = 0; i < r.Length; i++)
                        r[i] = (long)(a + i * stepSize);
                }
            }

            if (a < b)
            {
                if (r[r.Length - 1] > b)
                    r[r.Length - 1] = b;
            }
            else
            {
                if (r[r.Length - 1] > a)
                    r[r.Length - 1] = a;
            }

            return r;
        }

        /// <summary>
        ///   Enumerates through a range (like Python's xrange function).
        /// </summary>
        /// 
        /// <param name="a">The inclusive lower bound of the range.</param>
        /// <param name="b">The exclusive upper bound of the range.</param>
        /// <param name="stepSize">The step size to be taken between elements. 
        ///   This parameter can be negative to create a decreasing range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static IEnumerable<long> EnumerableRange(long a, long b, long stepSize)
        {
            if (a == b)
                yield break;

            if (stepSize == 0)
                throw new ArgumentOutOfRangeException("stepSize", "stepSize must be different from zero.");

            long last;

            if (a < b)
            {
                if (stepSize < 0)
                    throw new ArgumentOutOfRangeException("stepSize", "If a < b, stepSize must be positive.");

                uint steps = (uint)System.Math.Ceiling(((double)(b - a) / (double)stepSize)) - 1;
                for (uint i = 0; i < steps; i++)
                    yield return (long)(a +  i * stepSize);
                last = (long)(a +  steps * stepSize);
            }
            else
            {
                if (stepSize > 0)
                {
                    uint steps = (uint)System.Math.Ceiling(((double)(a - b) / (double)stepSize)) - 1;
                    for (uint i = 0; i < steps; i++)
                        yield return (long)(a - i * stepSize);
                    last = (long)(a - steps * stepSize);
                }
                else
                {
                    uint steps = (uint)System.Math.Ceiling(((double)(b - a) / (double)stepSize)) - 1;
                    for (uint i = 0; i < steps; i++)
                        yield return (long)(a + i * stepSize);
                    last = (long)(a + steps * stepSize);
                }
            }

            if (a < b)
            {
                yield return last > b ? b : last;
            }
            else
            {
                yield return last > a ? a : last;
            }
        }

        /// <summary>
        ///   Creates a range vector (like NumPy's arange function).
        /// </summary>
        /// 
        /// <param name="n">The exclusive upper bound of the range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static decimal[] Range(decimal n)
        {
            decimal[] r = new decimal[(int)n]; 
            for (int i = 0; i < r.Length; i++)
                r[i] = (decimal)i;
            return r;
        }

        /// <summary>
        ///   Creates a range vector (like NumPy's arange function).
        /// </summary>
        ///
        /// <param name="a">The inclusive lower bound of the range.</param>
        /// <param name="b">The exclusive upper bound of the range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static decimal[] Range(decimal a, decimal b)
        {
            if (a == b)
                return new decimal[] { };

            decimal[] r;

            if (b > a)
            {
                r = new decimal[(int)(b - a)];
                for (int i = 0; i < r.Length; i++)
                    r[i] = (decimal)(a++);
            }
            else
            {
                r = new decimal[(int)(a - b)];
                for (int i = 0; i < r.Length; i++)
                    r[i] = (decimal)(a--);
            }

            return r;
        }

        /// <summary>
        ///   Enumerates through a range (like Python's xrange function).
        /// </summary>
        /// 
        /// <param name="n">The exclusive upper bound of the range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static IEnumerable<decimal> EnumerableRange(decimal n)
        {
            for (decimal i = 0; i < n; i++)
                yield return (decimal)i;
        }

        /// <summary>
        ///   Enumerates through a range (like Python's xrange).
        /// </summary>
        /// 
        /// <param name="a">The inclusive lower bound of the range.</param>
        /// <param name="b">The exclusive upper bound of the range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static IEnumerable<decimal> EnumerableRange(decimal a, decimal b)
        {
            if (a == b)
                yield break;

            if (b > a)
            {
                int n = (int)(b - a);
                for (int i = 0; i < n; i++)
                    yield return (decimal)(a++);
            }
            else
            {
                int n = (int)(a - b);
                for (int i = 0; i < n; i++)
                    yield return (decimal)(a--);
            }
        }


        /// <summary>
        ///   Creates a range vector (like NumPy's arange function).
        /// </summary>
        /// 
        /// <param name="a">The inclusive lower bound of the range.</param>
        /// <param name="b">The exclusive upper bound of the range.</param>
        /// <param name="stepSize">The step size to be taken between elements. 
        ///   This parameter can be negative to create a decreasing range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static decimal[] Range(decimal a, decimal b, decimal stepSize)
        {
            if (a == b)
                return new decimal[] { };

            if (stepSize == 0)
                throw new ArgumentOutOfRangeException("stepSize", "stepSize must be different from zero.");

            decimal[] r;

            if (a < b)
            {
                if (stepSize < 0)
                    throw new ArgumentOutOfRangeException("stepSize", "If a < b, stepSize must be positive.");

                uint steps = (uint)System.Math.Ceiling(((decimal)(b - a) / (decimal)stepSize));

                r = new decimal[steps];
                for (uint i = 0; i < r.Length; i++)
                    r[i] = (decimal)(a +  i * stepSize);
            }
            else
            {
                if (stepSize > 0)
                {
                    uint steps = (uint)System.Math.Ceiling(((decimal)(a - b) / (decimal)stepSize));
                    r = new decimal[steps];
                    for (uint i = 0; i < r.Length; i++)
                        r[i] = (decimal)(a - i * stepSize);
                }
                else
                {
                    uint steps = (uint)System.Math.Ceiling(((decimal)(b - a) / (decimal)stepSize));
                    r = new decimal[steps];
                    for (uint i = 0; i < r.Length; i++)
                        r[i] = (decimal)(a + i * stepSize);
                }
            }

            if (a < b)
            {
                if (r[r.Length - 1] > b)
                    r[r.Length - 1] = b;
            }
            else
            {
                if (r[r.Length - 1] > a)
                    r[r.Length - 1] = a;
            }

            return r;
        }

        /// <summary>
        ///   Enumerates through a range (like Python's xrange function).
        /// </summary>
        /// 
        /// <param name="a">The inclusive lower bound of the range.</param>
        /// <param name="b">The exclusive upper bound of the range.</param>
        /// <param name="stepSize">The step size to be taken between elements. 
        ///   This parameter can be negative to create a decreasing range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static IEnumerable<decimal> EnumerableRange(decimal a, decimal b, decimal stepSize)
        {
            if (a == b)
                yield break;

            if (stepSize == 0)
                throw new ArgumentOutOfRangeException("stepSize", "stepSize must be different from zero.");

            decimal last;

            if (a < b)
            {
                if (stepSize < 0)
                    throw new ArgumentOutOfRangeException("stepSize", "If a < b, stepSize must be positive.");

                uint steps = (uint)System.Math.Ceiling(((decimal)(b - a) / (decimal)stepSize)) - 1;
                for (uint i = 0; i < steps; i++)
                    yield return (decimal)(a +  i * stepSize);
                last = (decimal)(a +  steps * stepSize);
            }
            else
            {
                if (stepSize > 0)
                {
                    uint steps = (uint)System.Math.Ceiling(((decimal)(a - b) / (decimal)stepSize)) - 1;
                    for (uint i = 0; i < steps; i++)
                        yield return (decimal)(a - i * stepSize);
                    last = (decimal)(a - steps * stepSize);
                }
                else
                {
                    uint steps = (uint)System.Math.Ceiling(((decimal)(b - a) / (decimal)stepSize)) - 1;
                    for (uint i = 0; i < steps; i++)
                        yield return (decimal)(a + i * stepSize);
                    last = (decimal)(a + steps * stepSize);
                }
            }

            if (a < b)
            {
                yield return last > b ? b : last;
            }
            else
            {
                yield return last > a ? a : last;
            }
        }

        /// <summary>
        ///   Creates a range vector (like NumPy's arange function).
        /// </summary>
        /// 
        /// <param name="n">The exclusive upper bound of the range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static ulong[] Range(ulong n)
        {
            ulong[] r = new ulong[(int)n]; 
            for (int i = 0; i < r.Length; i++)
                r[i] = (ulong)i;
            return r;
        }

        /// <summary>
        ///   Creates a range vector (like NumPy's arange function).
        /// </summary>
        ///
        /// <param name="a">The inclusive lower bound of the range.</param>
        /// <param name="b">The exclusive upper bound of the range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static ulong[] Range(ulong a, ulong b)
        {
            if (a == b)
                return new ulong[] { };

            ulong[] r;

            if (b > a)
            {
                r = new ulong[(int)(b - a)];
                for (int i = 0; i < r.Length; i++)
                    r[i] = (ulong)(a++);
            }
            else
            {
                r = new ulong[(int)(a - b)];
                for (int i = 0; i < r.Length; i++)
                    r[i] = (ulong)(a--);
            }

            return r;
        }

        /// <summary>
        ///   Enumerates through a range (like Python's xrange function).
        /// </summary>
        /// 
        /// <param name="n">The exclusive upper bound of the range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static IEnumerable<ulong> EnumerableRange(ulong n)
        {
            for (ulong i = 0; i < n; i++)
                yield return (ulong)i;
        }

        /// <summary>
        ///   Enumerates through a range (like Python's xrange).
        /// </summary>
        /// 
        /// <param name="a">The inclusive lower bound of the range.</param>
        /// <param name="b">The exclusive upper bound of the range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static IEnumerable<ulong> EnumerableRange(ulong a, ulong b)
        {
            if (a == b)
                yield break;

            if (b > a)
            {
                int n = (int)(b - a);
                for (int i = 0; i < n; i++)
                    yield return (ulong)(a++);
            }
            else
            {
                int n = (int)(a - b);
                for (int i = 0; i < n; i++)
                    yield return (ulong)(a--);
            }
        }


        /// <summary>
        ///   Creates a range vector (like NumPy's arange function).
        /// </summary>
        /// 
        /// <param name="a">The inclusive lower bound of the range.</param>
        /// <param name="b">The exclusive upper bound of the range.</param>
        /// <param name="stepSize">The step size to be taken between elements. 
        ///   This parameter can be negative to create a decreasing range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static float[] Range(ulong a, ulong b, float stepSize)
        {
            if (a == b)
                return new float[] { };

            if (stepSize == 0)
                throw new ArgumentOutOfRangeException("stepSize", "stepSize must be different from zero.");

            float[] r;

            if (a < b)
            {
                if (stepSize < 0)
                    throw new ArgumentOutOfRangeException("stepSize", "If a < b, stepSize must be positive.");

                uint steps = (uint)System.Math.Ceiling(((float)(b - a) / (float)stepSize));

                r = new float[steps];
                for (uint i = 0; i < r.Length; i++)
                    r[i] = (float)(a +  i * stepSize);
            }
            else
            {
                if (stepSize > 0)
                {
                    uint steps = (uint)System.Math.Ceiling(((float)(a - b) / (float)stepSize));
                    r = new float[steps];
                    for (uint i = 0; i < r.Length; i++)
                        r[i] = (float)(a - i * stepSize);
                }
                else
                {
                    uint steps = (uint)System.Math.Ceiling(((float)(b - a) / (float)stepSize));
                    r = new float[steps];
                    for (uint i = 0; i < r.Length; i++)
                        r[i] = (float)(a + i * stepSize);
                }
            }

            if (a < b)
            {
                if (r[r.Length - 1] > b)
                    r[r.Length - 1] = b;
            }
            else
            {
                if (r[r.Length - 1] > a)
                    r[r.Length - 1] = a;
            }

            return r;
        }

        /// <summary>
        ///   Enumerates through a range (like Python's xrange function).
        /// </summary>
        /// 
        /// <param name="a">The inclusive lower bound of the range.</param>
        /// <param name="b">The exclusive upper bound of the range.</param>
        /// <param name="stepSize">The step size to be taken between elements. 
        ///   This parameter can be negative to create a decreasing range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static IEnumerable<float> EnumerableRange(ulong a, ulong b, float stepSize)
        {
            if (a == b)
                yield break;

            if (stepSize == 0)
                throw new ArgumentOutOfRangeException("stepSize", "stepSize must be different from zero.");

            float last;

            if (a < b)
            {
                if (stepSize < 0)
                    throw new ArgumentOutOfRangeException("stepSize", "If a < b, stepSize must be positive.");

                uint steps = (uint)System.Math.Ceiling(((float)(b - a) / (float)stepSize)) - 1;
                for (uint i = 0; i < steps; i++)
                    yield return (float)(a +  i * stepSize);
                last = (float)(a +  steps * stepSize);
            }
            else
            {
                if (stepSize > 0)
                {
                    uint steps = (uint)System.Math.Ceiling(((float)(a - b) / (float)stepSize)) - 1;
                    for (uint i = 0; i < steps; i++)
                        yield return (float)(a - i * stepSize);
                    last = (float)(a - steps * stepSize);
                }
                else
                {
                    uint steps = (uint)System.Math.Ceiling(((float)(b - a) / (float)stepSize)) - 1;
                    for (uint i = 0; i < steps; i++)
                        yield return (float)(a + i * stepSize);
                    last = (float)(a + steps * stepSize);
                }
            }

            if (a < b)
            {
                yield return last > b ? b : last;
            }
            else
            {
                yield return last > a ? a : last;
            }
        }

        /// <summary>
        ///   Creates a range vector (like NumPy's arange function).
        /// </summary>
        /// 
        /// <param name="a">The inclusive lower bound of the range.</param>
        /// <param name="b">The exclusive upper bound of the range.</param>
        /// <param name="stepSize">The step size to be taken between elements. 
        ///   This parameter can be negative to create a decreasing range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static double[] Range(ulong a, ulong b, double stepSize)
        {
            if (a == b)
                return new double[] { };

            if (stepSize == 0)
                throw new ArgumentOutOfRangeException("stepSize", "stepSize must be different from zero.");

            double[] r;

            if (a < b)
            {
                if (stepSize < 0)
                    throw new ArgumentOutOfRangeException("stepSize", "If a < b, stepSize must be positive.");

                uint steps = (uint)System.Math.Ceiling(((double)(b - a) / (double)stepSize));

                r = new double[steps];
                for (uint i = 0; i < r.Length; i++)
                    r[i] = (double)(a +  i * stepSize);
            }
            else
            {
                if (stepSize > 0)
                {
                    uint steps = (uint)System.Math.Ceiling(((double)(a - b) / (double)stepSize));
                    r = new double[steps];
                    for (uint i = 0; i < r.Length; i++)
                        r[i] = (double)(a - i * stepSize);
                }
                else
                {
                    uint steps = (uint)System.Math.Ceiling(((double)(b - a) / (double)stepSize));
                    r = new double[steps];
                    for (uint i = 0; i < r.Length; i++)
                        r[i] = (double)(a + i * stepSize);
                }
            }

            if (a < b)
            {
                if (r[r.Length - 1] > b)
                    r[r.Length - 1] = b;
            }
            else
            {
                if (r[r.Length - 1] > a)
                    r[r.Length - 1] = a;
            }

            return r;
        }

        /// <summary>
        ///   Enumerates through a range (like Python's xrange function).
        /// </summary>
        /// 
        /// <param name="a">The inclusive lower bound of the range.</param>
        /// <param name="b">The exclusive upper bound of the range.</param>
        /// <param name="stepSize">The step size to be taken between elements. 
        ///   This parameter can be negative to create a decreasing range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static IEnumerable<double> EnumerableRange(ulong a, ulong b, double stepSize)
        {
            if (a == b)
                yield break;

            if (stepSize == 0)
                throw new ArgumentOutOfRangeException("stepSize", "stepSize must be different from zero.");

            double last;

            if (a < b)
            {
                if (stepSize < 0)
                    throw new ArgumentOutOfRangeException("stepSize", "If a < b, stepSize must be positive.");

                uint steps = (uint)System.Math.Ceiling(((double)(b - a) / (double)stepSize)) - 1;
                for (uint i = 0; i < steps; i++)
                    yield return (double)(a +  i * stepSize);
                last = (double)(a +  steps * stepSize);
            }
            else
            {
                if (stepSize > 0)
                {
                    uint steps = (uint)System.Math.Ceiling(((double)(a - b) / (double)stepSize)) - 1;
                    for (uint i = 0; i < steps; i++)
                        yield return (double)(a - i * stepSize);
                    last = (double)(a - steps * stepSize);
                }
                else
                {
                    uint steps = (uint)System.Math.Ceiling(((double)(b - a) / (double)stepSize)) - 1;
                    for (uint i = 0; i < steps; i++)
                        yield return (double)(a + i * stepSize);
                    last = (double)(a + steps * stepSize);
                }
            }

            if (a < b)
            {
                yield return last > b ? b : last;
            }
            else
            {
                yield return last > a ? a : last;
            }
        }

        /// <summary>
        ///   Creates a range vector (like NumPy's arange function).
        /// </summary>
        /// 
        /// <param name="a">The inclusive lower bound of the range.</param>
        /// <param name="b">The exclusive upper bound of the range.</param>
        /// <param name="stepSize">The step size to be taken between elements. 
        ///   This parameter can be negative to create a decreasing range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static ulong[] Range(ulong a, ulong b, ulong stepSize)
        {
            if (a == b)
                return new ulong[] { };

            if (stepSize == 0)
                throw new ArgumentOutOfRangeException("stepSize", "stepSize must be different from zero.");

            ulong[] r;

            if (a < b)
            {
                if (stepSize < 0)
                    throw new ArgumentOutOfRangeException("stepSize", "If a < b, stepSize must be positive.");

                uint steps = (uint)System.Math.Ceiling(((double)(b - a) / (double)stepSize));

                r = new ulong[steps];
                for (uint i = 0; i < r.Length; i++)
                    r[i] = (ulong)(a +  i * stepSize);
            }
            else
            {
                if (stepSize > 0)
                {
                    uint steps = (uint)System.Math.Ceiling(((double)(a - b) / (double)stepSize));
                    r = new ulong[steps];
                    for (uint i = 0; i < r.Length; i++)
                        r[i] = (ulong)(a - i * stepSize);
                }
                else
                {
                    uint steps = (uint)System.Math.Ceiling(((double)(b - a) / (double)stepSize));
                    r = new ulong[steps];
                    for (uint i = 0; i < r.Length; i++)
                        r[i] = (ulong)(a + i * stepSize);
                }
            }

            if (a < b)
            {
                if (r[r.Length - 1] > b)
                    r[r.Length - 1] = b;
            }
            else
            {
                if (r[r.Length - 1] > a)
                    r[r.Length - 1] = a;
            }

            return r;
        }

        /// <summary>
        ///   Enumerates through a range (like Python's xrange function).
        /// </summary>
        /// 
        /// <param name="a">The inclusive lower bound of the range.</param>
        /// <param name="b">The exclusive upper bound of the range.</param>
        /// <param name="stepSize">The step size to be taken between elements. 
        ///   This parameter can be negative to create a decreasing range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static IEnumerable<ulong> EnumerableRange(ulong a, ulong b, ulong stepSize)
        {
            if (a == b)
                yield break;

            if (stepSize == 0)
                throw new ArgumentOutOfRangeException("stepSize", "stepSize must be different from zero.");

            ulong last;

            if (a < b)
            {
                if (stepSize < 0)
                    throw new ArgumentOutOfRangeException("stepSize", "If a < b, stepSize must be positive.");

                uint steps = (uint)System.Math.Ceiling(((double)(b - a) / (double)stepSize)) - 1;
                for (uint i = 0; i < steps; i++)
                    yield return (ulong)(a +  i * stepSize);
                last = (ulong)(a +  steps * stepSize);
            }
            else
            {
                if (stepSize > 0)
                {
                    uint steps = (uint)System.Math.Ceiling(((double)(a - b) / (double)stepSize)) - 1;
                    for (uint i = 0; i < steps; i++)
                        yield return (ulong)(a - i * stepSize);
                    last = (ulong)(a - steps * stepSize);
                }
                else
                {
                    uint steps = (uint)System.Math.Ceiling(((double)(b - a) / (double)stepSize)) - 1;
                    for (uint i = 0; i < steps; i++)
                        yield return (ulong)(a + i * stepSize);
                    last = (ulong)(a + steps * stepSize);
                }
            }

            if (a < b)
            {
                yield return last > b ? b : last;
            }
            else
            {
                yield return last > a ? a : last;
            }
        }

        /// <summary>
        ///   Creates a range vector (like NumPy's arange function).
        /// </summary>
        /// 
        /// <param name="n">The exclusive upper bound of the range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static ushort[] Range(ushort n)
        {
            ushort[] r = new ushort[(int)n]; 
            for (int i = 0; i < r.Length; i++)
                r[i] = (ushort)i;
            return r;
        }

        /// <summary>
        ///   Creates a range vector (like NumPy's arange function).
        /// </summary>
        ///
        /// <param name="a">The inclusive lower bound of the range.</param>
        /// <param name="b">The exclusive upper bound of the range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static ushort[] Range(ushort a, ushort b)
        {
            if (a == b)
                return new ushort[] { };

            ushort[] r;

            if (b > a)
            {
                r = new ushort[(int)(b - a)];
                for (int i = 0; i < r.Length; i++)
                    r[i] = (ushort)(a++);
            }
            else
            {
                r = new ushort[(int)(a - b)];
                for (int i = 0; i < r.Length; i++)
                    r[i] = (ushort)(a--);
            }

            return r;
        }

        /// <summary>
        ///   Enumerates through a range (like Python's xrange function).
        /// </summary>
        /// 
        /// <param name="n">The exclusive upper bound of the range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static IEnumerable<ushort> EnumerableRange(ushort n)
        {
            for (ushort i = 0; i < n; i++)
                yield return (ushort)i;
        }

        /// <summary>
        ///   Enumerates through a range (like Python's xrange).
        /// </summary>
        /// 
        /// <param name="a">The inclusive lower bound of the range.</param>
        /// <param name="b">The exclusive upper bound of the range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static IEnumerable<ushort> EnumerableRange(ushort a, ushort b)
        {
            if (a == b)
                yield break;

            if (b > a)
            {
                int n = (int)(b - a);
                for (int i = 0; i < n; i++)
                    yield return (ushort)(a++);
            }
            else
            {
                int n = (int)(a - b);
                for (int i = 0; i < n; i++)
                    yield return (ushort)(a--);
            }
        }


        /// <summary>
        ///   Creates a range vector (like NumPy's arange function).
        /// </summary>
        /// 
        /// <param name="a">The inclusive lower bound of the range.</param>
        /// <param name="b">The exclusive upper bound of the range.</param>
        /// <param name="stepSize">The step size to be taken between elements. 
        ///   This parameter can be negative to create a decreasing range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static float[] Range(ushort a, ushort b, float stepSize)
        {
            if (a == b)
                return new float[] { };

            if (stepSize == 0)
                throw new ArgumentOutOfRangeException("stepSize", "stepSize must be different from zero.");

            float[] r;

            if (a < b)
            {
                if (stepSize < 0)
                    throw new ArgumentOutOfRangeException("stepSize", "If a < b, stepSize must be positive.");

                uint steps = (uint)System.Math.Ceiling(((float)(b - a) / (float)stepSize));

                r = new float[steps];
                for (uint i = 0; i < r.Length; i++)
                    r[i] = (float)(a +  i * stepSize);
            }
            else
            {
                if (stepSize > 0)
                {
                    uint steps = (uint)System.Math.Ceiling(((float)(a - b) / (float)stepSize));
                    r = new float[steps];
                    for (uint i = 0; i < r.Length; i++)
                        r[i] = (float)(a - i * stepSize);
                }
                else
                {
                    uint steps = (uint)System.Math.Ceiling(((float)(b - a) / (float)stepSize));
                    r = new float[steps];
                    for (uint i = 0; i < r.Length; i++)
                        r[i] = (float)(a + i * stepSize);
                }
            }

            if (a < b)
            {
                if (r[r.Length - 1] > b)
                    r[r.Length - 1] = b;
            }
            else
            {
                if (r[r.Length - 1] > a)
                    r[r.Length - 1] = a;
            }

            return r;
        }

        /// <summary>
        ///   Enumerates through a range (like Python's xrange function).
        /// </summary>
        /// 
        /// <param name="a">The inclusive lower bound of the range.</param>
        /// <param name="b">The exclusive upper bound of the range.</param>
        /// <param name="stepSize">The step size to be taken between elements. 
        ///   This parameter can be negative to create a decreasing range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static IEnumerable<float> EnumerableRange(ushort a, ushort b, float stepSize)
        {
            if (a == b)
                yield break;

            if (stepSize == 0)
                throw new ArgumentOutOfRangeException("stepSize", "stepSize must be different from zero.");

            float last;

            if (a < b)
            {
                if (stepSize < 0)
                    throw new ArgumentOutOfRangeException("stepSize", "If a < b, stepSize must be positive.");

                uint steps = (uint)System.Math.Ceiling(((float)(b - a) / (float)stepSize)) - 1;
                for (uint i = 0; i < steps; i++)
                    yield return (float)(a +  i * stepSize);
                last = (float)(a +  steps * stepSize);
            }
            else
            {
                if (stepSize > 0)
                {
                    uint steps = (uint)System.Math.Ceiling(((float)(a - b) / (float)stepSize)) - 1;
                    for (uint i = 0; i < steps; i++)
                        yield return (float)(a - i * stepSize);
                    last = (float)(a - steps * stepSize);
                }
                else
                {
                    uint steps = (uint)System.Math.Ceiling(((float)(b - a) / (float)stepSize)) - 1;
                    for (uint i = 0; i < steps; i++)
                        yield return (float)(a + i * stepSize);
                    last = (float)(a + steps * stepSize);
                }
            }

            if (a < b)
            {
                yield return last > b ? b : last;
            }
            else
            {
                yield return last > a ? a : last;
            }
        }

        /// <summary>
        ///   Creates a range vector (like NumPy's arange function).
        /// </summary>
        /// 
        /// <param name="a">The inclusive lower bound of the range.</param>
        /// <param name="b">The exclusive upper bound of the range.</param>
        /// <param name="stepSize">The step size to be taken between elements. 
        ///   This parameter can be negative to create a decreasing range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static double[] Range(ushort a, ushort b, double stepSize)
        {
            if (a == b)
                return new double[] { };

            if (stepSize == 0)
                throw new ArgumentOutOfRangeException("stepSize", "stepSize must be different from zero.");

            double[] r;

            if (a < b)
            {
                if (stepSize < 0)
                    throw new ArgumentOutOfRangeException("stepSize", "If a < b, stepSize must be positive.");

                uint steps = (uint)System.Math.Ceiling(((double)(b - a) / (double)stepSize));

                r = new double[steps];
                for (uint i = 0; i < r.Length; i++)
                    r[i] = (double)(a +  i * stepSize);
            }
            else
            {
                if (stepSize > 0)
                {
                    uint steps = (uint)System.Math.Ceiling(((double)(a - b) / (double)stepSize));
                    r = new double[steps];
                    for (uint i = 0; i < r.Length; i++)
                        r[i] = (double)(a - i * stepSize);
                }
                else
                {
                    uint steps = (uint)System.Math.Ceiling(((double)(b - a) / (double)stepSize));
                    r = new double[steps];
                    for (uint i = 0; i < r.Length; i++)
                        r[i] = (double)(a + i * stepSize);
                }
            }

            if (a < b)
            {
                if (r[r.Length - 1] > b)
                    r[r.Length - 1] = b;
            }
            else
            {
                if (r[r.Length - 1] > a)
                    r[r.Length - 1] = a;
            }

            return r;
        }

        /// <summary>
        ///   Enumerates through a range (like Python's xrange function).
        /// </summary>
        /// 
        /// <param name="a">The inclusive lower bound of the range.</param>
        /// <param name="b">The exclusive upper bound of the range.</param>
        /// <param name="stepSize">The step size to be taken between elements. 
        ///   This parameter can be negative to create a decreasing range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static IEnumerable<double> EnumerableRange(ushort a, ushort b, double stepSize)
        {
            if (a == b)
                yield break;

            if (stepSize == 0)
                throw new ArgumentOutOfRangeException("stepSize", "stepSize must be different from zero.");

            double last;

            if (a < b)
            {
                if (stepSize < 0)
                    throw new ArgumentOutOfRangeException("stepSize", "If a < b, stepSize must be positive.");

                uint steps = (uint)System.Math.Ceiling(((double)(b - a) / (double)stepSize)) - 1;
                for (uint i = 0; i < steps; i++)
                    yield return (double)(a +  i * stepSize);
                last = (double)(a +  steps * stepSize);
            }
            else
            {
                if (stepSize > 0)
                {
                    uint steps = (uint)System.Math.Ceiling(((double)(a - b) / (double)stepSize)) - 1;
                    for (uint i = 0; i < steps; i++)
                        yield return (double)(a - i * stepSize);
                    last = (double)(a - steps * stepSize);
                }
                else
                {
                    uint steps = (uint)System.Math.Ceiling(((double)(b - a) / (double)stepSize)) - 1;
                    for (uint i = 0; i < steps; i++)
                        yield return (double)(a + i * stepSize);
                    last = (double)(a + steps * stepSize);
                }
            }

            if (a < b)
            {
                yield return last > b ? b : last;
            }
            else
            {
                yield return last > a ? a : last;
            }
        }

        /// <summary>
        ///   Creates a range vector (like NumPy's arange function).
        /// </summary>
        /// 
        /// <param name="a">The inclusive lower bound of the range.</param>
        /// <param name="b">The exclusive upper bound of the range.</param>
        /// <param name="stepSize">The step size to be taken between elements. 
        ///   This parameter can be negative to create a decreasing range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static ushort[] Range(ushort a, ushort b, ushort stepSize)
        {
            if (a == b)
                return new ushort[] { };

            if (stepSize == 0)
                throw new ArgumentOutOfRangeException("stepSize", "stepSize must be different from zero.");

            ushort[] r;

            if (a < b)
            {
                if (stepSize < 0)
                    throw new ArgumentOutOfRangeException("stepSize", "If a < b, stepSize must be positive.");

                uint steps = (uint)System.Math.Ceiling(((double)(b - a) / (double)stepSize));

                r = new ushort[steps];
                for (uint i = 0; i < r.Length; i++)
                    r[i] = (ushort)(a +  i * stepSize);
            }
            else
            {
                if (stepSize > 0)
                {
                    uint steps = (uint)System.Math.Ceiling(((double)(a - b) / (double)stepSize));
                    r = new ushort[steps];
                    for (uint i = 0; i < r.Length; i++)
                        r[i] = (ushort)(a - i * stepSize);
                }
                else
                {
                    uint steps = (uint)System.Math.Ceiling(((double)(b - a) / (double)stepSize));
                    r = new ushort[steps];
                    for (uint i = 0; i < r.Length; i++)
                        r[i] = (ushort)(a + i * stepSize);
                }
            }

            if (a < b)
            {
                if (r[r.Length - 1] > b)
                    r[r.Length - 1] = b;
            }
            else
            {
                if (r[r.Length - 1] > a)
                    r[r.Length - 1] = a;
            }

            return r;
        }

        /// <summary>
        ///   Enumerates through a range (like Python's xrange function).
        /// </summary>
        /// 
        /// <param name="a">The inclusive lower bound of the range.</param>
        /// <param name="b">The exclusive upper bound of the range.</param>
        /// <param name="stepSize">The step size to be taken between elements. 
        ///   This parameter can be negative to create a decreasing range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static IEnumerable<ushort> EnumerableRange(ushort a, ushort b, ushort stepSize)
        {
            if (a == b)
                yield break;

            if (stepSize == 0)
                throw new ArgumentOutOfRangeException("stepSize", "stepSize must be different from zero.");

            ushort last;

            if (a < b)
            {
                if (stepSize < 0)
                    throw new ArgumentOutOfRangeException("stepSize", "If a < b, stepSize must be positive.");

                uint steps = (uint)System.Math.Ceiling(((double)(b - a) / (double)stepSize)) - 1;
                for (uint i = 0; i < steps; i++)
                    yield return (ushort)(a +  i * stepSize);
                last = (ushort)(a +  steps * stepSize);
            }
            else
            {
                if (stepSize > 0)
                {
                    uint steps = (uint)System.Math.Ceiling(((double)(a - b) / (double)stepSize)) - 1;
                    for (uint i = 0; i < steps; i++)
                        yield return (ushort)(a - i * stepSize);
                    last = (ushort)(a - steps * stepSize);
                }
                else
                {
                    uint steps = (uint)System.Math.Ceiling(((double)(b - a) / (double)stepSize)) - 1;
                    for (uint i = 0; i < steps; i++)
                        yield return (ushort)(a + i * stepSize);
                    last = (ushort)(a + steps * stepSize);
                }
            }

            if (a < b)
            {
                yield return last > b ? b : last;
            }
            else
            {
                yield return last > a ? a : last;
            }
        }

        /// <summary>
        ///   Creates a range vector (like NumPy's arange function).
        /// </summary>
        /// 
        /// <param name="range">The range from where values should be created.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static double[] Range(this DoubleRange range)
        {
            return Range(range.Min, range.Max);
        }

        /// <summary>
        ///   Creates a range vector (like NumPy's arange function).
        /// </summary>
        /// 
        /// <param name="range">The range from where values should be created.</param>
		/// <param name="stepSize">The step size to be taken between elements. 
        ///   This parameter can be negative to create a decreasing range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static double[] Range(this DoubleRange range, double stepSize)
        {
            return Range(range.Min, range.Max, stepSize);
        }
        /// <summary>
        ///   Creates a range vector (like NumPy's arange function).
        /// </summary>
        /// 
        /// <param name="range">The range from where values should be created.</param>
		/// <param name="stepSize">The step size to be taken between elements. 
        ///   This parameter can be negative to create a decreasing range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static double[] Range(this DoubleRange range, float stepSize)
        {
            return Range(range.Min, range.Max, stepSize);
        }
        /// <summary>
        ///   Creates a range vector (like NumPy's arange function).
        /// </summary>
        /// 
        /// <param name="range">The range from where values should be created.</param>
		/// <param name="stepSize">The step size to be taken between elements. 
        ///   This parameter can be negative to create a decreasing range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static double[] Range(this DoubleRange range, byte stepSize)
        {
            return Range(range.Min, range.Max, stepSize);
        }
        /// <summary>
        ///   Creates a range vector (like NumPy's arange function).
        /// </summary>
        /// 
        /// <param name="range">The range from where values should be created.</param>
		/// <param name="stepSize">The step size to be taken between elements. 
        ///   This parameter can be negative to create a decreasing range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static double[] Range(this DoubleRange range, int stepSize)
        {
            return Range(range.Min, range.Max, stepSize);
        }

        /// <summary>
        ///   Creates a range vector (like NumPy's arange function).
        /// </summary>
        /// 
        /// <param name="range">The range from where values should be created.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static float[] Range(this Range range)
        {
            return Range(range.Min, range.Max);
        }

        /// <summary>
        ///   Creates a range vector (like NumPy's arange function).
        /// </summary>
        /// 
        /// <param name="range">The range from where values should be created.</param>
		/// <param name="stepSize">The step size to be taken between elements. 
        ///   This parameter can be negative to create a decreasing range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static double[] Range(this Range range, double stepSize)
        {
            return Range(range.Min, range.Max, stepSize);
        }
        /// <summary>
        ///   Creates a range vector (like NumPy's arange function).
        /// </summary>
        /// 
        /// <param name="range">The range from where values should be created.</param>
		/// <param name="stepSize">The step size to be taken between elements. 
        ///   This parameter can be negative to create a decreasing range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static float[] Range(this Range range, float stepSize)
        {
            return Range(range.Min, range.Max, stepSize);
        }
        /// <summary>
        ///   Creates a range vector (like NumPy's arange function).
        /// </summary>
        /// 
        /// <param name="range">The range from where values should be created.</param>
		/// <param name="stepSize">The step size to be taken between elements. 
        ///   This parameter can be negative to create a decreasing range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static float[] Range(this Range range, byte stepSize)
        {
            return Range(range.Min, range.Max, stepSize);
        }
        /// <summary>
        ///   Creates a range vector (like NumPy's arange function).
        /// </summary>
        /// 
        /// <param name="range">The range from where values should be created.</param>
		/// <param name="stepSize">The step size to be taken between elements. 
        ///   This parameter can be negative to create a decreasing range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static float[] Range(this Range range, int stepSize)
        {
            return Range(range.Min, range.Max, stepSize);
        }

        /// <summary>
        ///   Creates a range vector (like NumPy's arange function).
        /// </summary>
        /// 
        /// <param name="range">The range from where values should be created.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static byte[] Range(this ByteRange range)
        {
            return Range(range.Min, range.Max);
        }

        /// <summary>
        ///   Creates a range vector (like NumPy's arange function).
        /// </summary>
        /// 
        /// <param name="range">The range from where values should be created.</param>
		/// <param name="stepSize">The step size to be taken between elements. 
        ///   This parameter can be negative to create a decreasing range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static double[] Range(this ByteRange range, double stepSize)
        {
            return Range(range.Min, range.Max, stepSize);
        }
        /// <summary>
        ///   Creates a range vector (like NumPy's arange function).
        /// </summary>
        /// 
        /// <param name="range">The range from where values should be created.</param>
		/// <param name="stepSize">The step size to be taken between elements. 
        ///   This parameter can be negative to create a decreasing range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static float[] Range(this ByteRange range, float stepSize)
        {
            return Range(range.Min, range.Max, stepSize);
        }
        /// <summary>
        ///   Creates a range vector (like NumPy's arange function).
        /// </summary>
        /// 
        /// <param name="range">The range from where values should be created.</param>
		/// <param name="stepSize">The step size to be taken between elements. 
        ///   This parameter can be negative to create a decreasing range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static byte[] Range(this ByteRange range, byte stepSize)
        {
            return Range(range.Min, range.Max, stepSize);
        }

        /// <summary>
        ///   Creates a range vector (like NumPy's arange function).
        /// </summary>
        /// 
        /// <param name="range">The range from where values should be created.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static int[] Range(this IntRange range)
        {
            return Range(range.Min, range.Max);
        }

        /// <summary>
        ///   Creates a range vector (like NumPy's arange function).
        /// </summary>
        /// 
        /// <param name="range">The range from where values should be created.</param>
		/// <param name="stepSize">The step size to be taken between elements. 
        ///   This parameter can be negative to create a decreasing range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static double[] Range(this IntRange range, double stepSize)
        {
            return Range(range.Min, range.Max, stepSize);
        }
        /// <summary>
        ///   Creates a range vector (like NumPy's arange function).
        /// </summary>
        /// 
        /// <param name="range">The range from where values should be created.</param>
		/// <param name="stepSize">The step size to be taken between elements. 
        ///   This parameter can be negative to create a decreasing range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static float[] Range(this IntRange range, float stepSize)
        {
            return Range(range.Min, range.Max, stepSize);
        }
        /// <summary>
        ///   Creates a range vector (like NumPy's arange function).
        /// </summary>
        /// 
        /// <param name="range">The range from where values should be created.</param>
		/// <param name="stepSize">The step size to be taken between elements. 
        ///   This parameter can be negative to create a decreasing range.</param>
		///
        /// <remarks>
        /// <para>
        ///   The Range methods should be equivalent to NumPy's np.arange method, with one
        ///   single difference: when the intervals are inverted (i.e. a > b) and the step
        ///   size is negative, the framework still iterates over the range backwards, as 
        ///   if the step was negative.</para>
        /// <para>
        ///   This function never includes the upper bound of the range. For methods
        ///   that include it, please see the <see cref="Interval(int, int)"/> methods.</para>  
        /// </remarks>
        ///
        /// <seealso cref="Interval(int, int)"/>
        ///
        public static int[] Range(this IntRange range, int stepSize)
        {
            return Range(range.Min, range.Max, stepSize);
        }
    }
}